962 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * amc6821.c - Part of lm_sensors, Linux kernel modules for hardware4 * monitoring5 * Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>6 *7 * Based on max6650.c:8 * Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de>9 *10 * Conversion to regmap and with_info API:11 * Copyright (C) 2024 Guenter Roeck <linux@roeck-us.net>12 */13 14#include <linux/bitfield.h>15#include <linux/bitops.h>16#include <linux/bits.h>17#include <linux/err.h>18#include <linux/hwmon.h>19#include <linux/hwmon-sysfs.h>20#include <linux/i2c.h>21#include <linux/init.h>22#include <linux/minmax.h>23#include <linux/module.h>24#include <linux/mutex.h>25#include <linux/regmap.h>26#include <linux/slab.h>27 28/*29 * Addresses to scan.30 */31 32static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,33 0x4c, 0x4d, 0x4e, I2C_CLIENT_END};34 35/*36 * Insmod parameters37 */38 39static int pwminv; /*Inverted PWM output. */40module_param(pwminv, int, 0444);41 42static int init = 1; /*Power-on initialization.*/43module_param(init, int, 0444);44 45#define AMC6821_REG_DEV_ID 0x3D46#define AMC6821_REG_COMP_ID 0x3E47#define AMC6821_REG_CONF1 0x0048#define AMC6821_REG_CONF2 0x0149#define AMC6821_REG_CONF3 0x3F50#define AMC6821_REG_CONF4 0x0451#define AMC6821_REG_STAT1 0x0252#define AMC6821_REG_STAT2 0x0353#define AMC6821_REG_TEMP_LO 0x0654#define AMC6821_REG_TDATA_LOW 0x0855#define AMC6821_REG_TDATA_HI 0x0956#define AMC6821_REG_LTEMP_HI 0x0A57#define AMC6821_REG_RTEMP_HI 0x0B58#define AMC6821_REG_LTEMP_LIMIT_MIN 0x1559#define AMC6821_REG_LTEMP_LIMIT_MAX 0x1460#define AMC6821_REG_RTEMP_LIMIT_MIN 0x1961#define AMC6821_REG_RTEMP_LIMIT_MAX 0x1862#define AMC6821_REG_LTEMP_CRIT 0x1B63#define AMC6821_REG_RTEMP_CRIT 0x1D64#define AMC6821_REG_PSV_TEMP 0x1C65#define AMC6821_REG_DCY 0x2266#define AMC6821_REG_LTEMP_FAN_CTRL 0x2467#define AMC6821_REG_RTEMP_FAN_CTRL 0x2568#define AMC6821_REG_DCY_LOW_TEMP 0x2169 70#define AMC6821_REG_TACH_LLIMITL 0x1071#define AMC6821_REG_TACH_HLIMITL 0x1272#define AMC6821_REG_TACH_SETTINGL 0x1e73 74#define AMC6821_CONF1_START BIT(0)75#define AMC6821_CONF1_FAN_INT_EN BIT(1)76#define AMC6821_CONF1_FANIE BIT(2)77#define AMC6821_CONF1_PWMINV BIT(3)78#define AMC6821_CONF1_FAN_FAULT_EN BIT(4)79#define AMC6821_CONF1_FDRC0 BIT(5)80#define AMC6821_CONF1_FDRC1 BIT(6)81#define AMC6821_CONF1_THERMOVIE BIT(7)82 83#define AMC6821_CONF2_PWM_EN BIT(0)84#define AMC6821_CONF2_TACH_MODE BIT(1)85#define AMC6821_CONF2_TACH_EN BIT(2)86#define AMC6821_CONF2_RTFIE BIT(3)87#define AMC6821_CONF2_LTOIE BIT(4)88#define AMC6821_CONF2_RTOIE BIT(5)89#define AMC6821_CONF2_PSVIE BIT(6)90#define AMC6821_CONF2_RST BIT(7)91 92#define AMC6821_CONF3_THERM_FAN_EN BIT(7)93#define AMC6821_CONF3_REV_MASK GENMASK(3, 0)94 95#define AMC6821_CONF4_OVREN BIT(4)96#define AMC6821_CONF4_TACH_FAST BIT(5)97#define AMC6821_CONF4_PSPR BIT(6)98#define AMC6821_CONF4_MODE BIT(7)99 100#define AMC6821_STAT1_RPM_ALARM BIT(0)101#define AMC6821_STAT1_FANS BIT(1)102#define AMC6821_STAT1_RTH BIT(2)103#define AMC6821_STAT1_RTL BIT(3)104#define AMC6821_STAT1_R_THERM BIT(4)105#define AMC6821_STAT1_RTF BIT(5)106#define AMC6821_STAT1_LTH BIT(6)107#define AMC6821_STAT1_LTL BIT(7)108 109#define AMC6821_STAT2_RTC BIT(3)110#define AMC6821_STAT2_LTC BIT(4)111#define AMC6821_STAT2_LPSV BIT(5)112#define AMC6821_STAT2_L_THERM BIT(6)113#define AMC6821_STAT2_THERM_IN BIT(7)114 115#define AMC6821_TEMP_SLOPE_MASK GENMASK(2, 0)116#define AMC6821_TEMP_LIMIT_MASK GENMASK(7, 3)117 118/*119 * Client data (each client gets its own)120 */121 122struct amc6821_data {123 struct regmap *regmap;124 struct mutex update_lock;125};126 127/*128 * Return 0 on success or negative error code.129 *130 * temps returns set of three temperatures, in °C:131 * temps[0]: Passive cooling temperature, applies to both channels132 * temps[1]: Low temperature, start slope calculations133 * temps[2]: High temperature134 *135 * Channel 0: local, channel 1: remote.136 */137static int amc6821_get_auto_point_temps(struct regmap *regmap, int channel, u8 *temps)138{139 u32 regs[] = {140 AMC6821_REG_DCY_LOW_TEMP,141 AMC6821_REG_PSV_TEMP,142 channel ? AMC6821_REG_RTEMP_FAN_CTRL : AMC6821_REG_LTEMP_FAN_CTRL143 };144 u8 regvals[3];145 int slope;146 int err;147 148 err = regmap_multi_reg_read(regmap, regs, regvals, 3);149 if (err)150 return err;151 temps[0] = regvals[1];152 temps[1] = FIELD_GET(AMC6821_TEMP_LIMIT_MASK, regvals[2]) * 4;153 154 /* slope is 32 >> <slope bits> in °C */155 slope = 32 >> FIELD_GET(AMC6821_TEMP_SLOPE_MASK, regvals[2]);156 if (slope)157 temps[2] = temps[1] + DIV_ROUND_CLOSEST(255 - regvals[0], slope);158 else159 temps[2] = 255;160 161 return 0;162}163 164static int amc6821_temp_read_values(struct regmap *regmap, u32 attr, int channel, long *val)165{166 int reg, err;167 u32 regval;168 169 switch (attr) {170 case hwmon_temp_input:171 reg = channel ? AMC6821_REG_RTEMP_HI : AMC6821_REG_LTEMP_HI;172 break;173 case hwmon_temp_min:174 reg = channel ? AMC6821_REG_RTEMP_LIMIT_MIN : AMC6821_REG_LTEMP_LIMIT_MIN;175 break;176 case hwmon_temp_max:177 reg = channel ? AMC6821_REG_RTEMP_LIMIT_MAX : AMC6821_REG_LTEMP_LIMIT_MAX;178 break;179 case hwmon_temp_crit:180 reg = channel ? AMC6821_REG_RTEMP_CRIT : AMC6821_REG_LTEMP_CRIT;181 break;182 default:183 return -EOPNOTSUPP;184 }185 err = regmap_read(regmap, reg, ®val);186 if (err)187 return err;188 *val = sign_extend32(regval, 7) * 1000;189 return 0;190}191 192static int amc6821_read_alarms(struct regmap *regmap, enum hwmon_sensor_types type,193 u32 attr, int channel, long *val)194{195 int reg, mask, err;196 u32 regval;197 198 switch (type) {199 case hwmon_temp:200 switch (attr) {201 case hwmon_temp_min_alarm:202 reg = AMC6821_REG_STAT1;203 mask = channel ? AMC6821_STAT1_RTL : AMC6821_STAT1_LTL;204 break;205 case hwmon_temp_max_alarm:206 reg = AMC6821_REG_STAT1;207 mask = channel ? AMC6821_STAT1_RTH : AMC6821_STAT1_LTH;208 break;209 case hwmon_temp_crit_alarm:210 reg = AMC6821_REG_STAT2;211 mask = channel ? AMC6821_STAT2_RTC : AMC6821_STAT2_LTC;212 break;213 case hwmon_temp_fault:214 reg = AMC6821_REG_STAT1;215 mask = AMC6821_STAT1_RTF;216 break;217 default:218 return -EOPNOTSUPP;219 }220 break;221 case hwmon_fan:222 switch (attr) {223 case hwmon_fan_fault:224 reg = AMC6821_REG_STAT1;225 mask = AMC6821_STAT1_FANS;226 break;227 default:228 return -EOPNOTSUPP;229 }230 break;231 default:232 return -EOPNOTSUPP;233 }234 err = regmap_read(regmap, reg, ®val);235 if (err)236 return err;237 *val = !!(regval & mask);238 return 0;239}240 241static int amc6821_temp_read(struct device *dev, u32 attr, int channel, long *val)242{243 struct amc6821_data *data = dev_get_drvdata(dev);244 245 switch (attr) {246 case hwmon_temp_input:247 case hwmon_temp_min:248 case hwmon_temp_max:249 case hwmon_temp_crit:250 return amc6821_temp_read_values(data->regmap, attr, channel, val);251 case hwmon_temp_min_alarm:252 case hwmon_temp_max_alarm:253 case hwmon_temp_crit_alarm:254 case hwmon_temp_fault:255 return amc6821_read_alarms(data->regmap, hwmon_temp, attr, channel, val);256 default:257 return -EOPNOTSUPP;258 }259}260 261static int amc6821_temp_write(struct device *dev, u32 attr, int channel, long val)262{263 struct amc6821_data *data = dev_get_drvdata(dev);264 int reg;265 266 val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);267 268 switch (attr) {269 case hwmon_temp_min:270 reg = channel ? AMC6821_REG_RTEMP_LIMIT_MIN : AMC6821_REG_LTEMP_LIMIT_MIN;271 break;272 case hwmon_temp_max:273 reg = channel ? AMC6821_REG_RTEMP_LIMIT_MAX : AMC6821_REG_LTEMP_LIMIT_MAX;274 break;275 case hwmon_temp_crit:276 reg = channel ? AMC6821_REG_RTEMP_CRIT : AMC6821_REG_LTEMP_CRIT;277 break;278 default:279 return -EOPNOTSUPP;280 }281 return regmap_write(data->regmap, reg, val);282}283 284static int amc6821_pwm_read(struct device *dev, u32 attr, long *val)285{286 struct amc6821_data *data = dev_get_drvdata(dev);287 struct regmap *regmap = data->regmap;288 u32 regval;289 int err;290 291 switch (attr) {292 case hwmon_pwm_enable:293 err = regmap_read(regmap, AMC6821_REG_CONF1, ®val);294 if (err)295 return err;296 switch (regval & (AMC6821_CONF1_FDRC0 | AMC6821_CONF1_FDRC1)) {297 case 0:298 *val = 1; /* manual */299 break;300 case AMC6821_CONF1_FDRC0:301 *val = 4; /* target rpm (fan1_target) controlled */302 break;303 case AMC6821_CONF1_FDRC1:304 *val = 2; /* remote temp controlled */305 break;306 default:307 *val = 3; /* max(local, remote) temp controlled */308 break;309 }310 return 0;311 case hwmon_pwm_mode:312 err = regmap_read(regmap, AMC6821_REG_CONF2, ®val);313 if (err)314 return err;315 *val = !!(regval & AMC6821_CONF2_TACH_MODE);316 return 0;317 case hwmon_pwm_auto_channels_temp:318 err = regmap_read(regmap, AMC6821_REG_CONF1, ®val);319 if (err)320 return err;321 switch (regval & (AMC6821_CONF1_FDRC0 | AMC6821_CONF1_FDRC1)) {322 case 0:323 case AMC6821_CONF1_FDRC0:324 *val = 0; /* manual or target rpm controlled */325 break;326 case AMC6821_CONF1_FDRC1:327 *val = 2; /* remote temp controlled */328 break;329 default:330 *val = 3; /* max(local, remote) temp controlled */331 break;332 }333 return 0;334 case hwmon_pwm_input:335 err = regmap_read(regmap, AMC6821_REG_DCY, ®val);336 if (err)337 return err;338 *val = regval;339 return 0;340 default:341 return -EOPNOTSUPP;342 }343}344 345static int amc6821_pwm_write(struct device *dev, u32 attr, long val)346{347 struct amc6821_data *data = dev_get_drvdata(dev);348 struct regmap *regmap = data->regmap;349 u32 mode;350 351 switch (attr) {352 case hwmon_pwm_enable:353 switch (val) {354 case 1:355 mode = 0;356 break;357 case 2:358 mode = AMC6821_CONF1_FDRC1;359 break;360 case 3:361 mode = AMC6821_CONF1_FDRC0 | AMC6821_CONF1_FDRC1;362 break;363 case 4:364 mode = AMC6821_CONF1_FDRC0;365 break;366 default:367 return -EINVAL;368 }369 return regmap_update_bits(regmap, AMC6821_REG_CONF1,370 AMC6821_CONF1_FDRC0 | AMC6821_CONF1_FDRC1,371 mode);372 case hwmon_pwm_mode:373 if (val < 0 || val > 1)374 return -EINVAL;375 return regmap_update_bits(regmap, AMC6821_REG_CONF2,376 AMC6821_CONF2_TACH_MODE,377 val ? AMC6821_CONF2_TACH_MODE : 0);378 break;379 case hwmon_pwm_input:380 if (val < 0 || val > 255)381 return -EINVAL;382 return regmap_write(regmap, AMC6821_REG_DCY, val);383 default:384 return -EOPNOTSUPP;385 }386}387 388static int amc6821_fan_read_rpm(struct regmap *regmap, u32 attr, long *val)389{390 int reg, err;391 u8 regs[2];392 u32 regval;393 394 switch (attr) {395 case hwmon_fan_input:396 reg = AMC6821_REG_TDATA_LOW;397 break;398 case hwmon_fan_min:399 reg = AMC6821_REG_TACH_LLIMITL;400 break;401 case hwmon_fan_max:402 reg = AMC6821_REG_TACH_HLIMITL;403 break;404 case hwmon_fan_target:405 reg = AMC6821_REG_TACH_SETTINGL;406 break;407 default:408 return -EOPNOTSUPP;409 }410 411 err = regmap_bulk_read(regmap, reg, regs, 2);412 if (err)413 return err;414 415 regval = (regs[1] << 8) | regs[0];416 *val = regval ? 6000000 / regval : 0;417 418 return 0;419}420 421static int amc6821_fan_read(struct device *dev, u32 attr, long *val)422{423 struct amc6821_data *data = dev_get_drvdata(dev);424 struct regmap *regmap = data->regmap;425 u32 regval;426 int err;427 428 switch (attr) {429 case hwmon_fan_input:430 case hwmon_fan_min:431 case hwmon_fan_max:432 case hwmon_fan_target:433 return amc6821_fan_read_rpm(regmap, attr, val);434 case hwmon_fan_fault:435 return amc6821_read_alarms(regmap, hwmon_fan, attr, 0, val);436 case hwmon_fan_pulses:437 err = regmap_read(regmap, AMC6821_REG_CONF4, ®val);438 if (err)439 return err;440 *val = (regval & AMC6821_CONF4_PSPR) ? 4 : 2;441 return 0;442 default:443 return -EOPNOTSUPP;444 }445}446 447static int amc6821_fan_write(struct device *dev, u32 attr, long val)448{449 struct amc6821_data *data = dev_get_drvdata(dev);450 struct regmap *regmap = data->regmap;451 u8 regs[2];452 int reg;453 454 if (attr == hwmon_fan_pulses) {455 if (val != 2 && val != 4)456 return -EINVAL;457 return regmap_update_bits(regmap, AMC6821_REG_CONF4,458 AMC6821_CONF4_PSPR,459 val == 4 ? AMC6821_CONF4_PSPR : 0);460 }461 462 if (val < 0)463 return -EINVAL;464 465 switch (attr) {466 case hwmon_fan_min:467 if (!val) /* no unlimited minimum speed */468 return -EINVAL;469 reg = AMC6821_REG_TACH_LLIMITL;470 break;471 case hwmon_fan_max:472 reg = AMC6821_REG_TACH_HLIMITL;473 break;474 case hwmon_fan_target:475 if (!val) /* no unlimited target speed */476 return -EINVAL;477 reg = AMC6821_REG_TACH_SETTINGL;478 break;479 default:480 return -EOPNOTSUPP;481 }482 483 val = val ? 6000000 / clamp_val(val, 1, 6000000) : 0;484 val = clamp_val(val, 0, 0xffff);485 486 regs[0] = val & 0xff;487 regs[1] = val >> 8;488 489 return regmap_bulk_write(data->regmap, reg, regs, 2);490}491 492static ssize_t temp_auto_point_temp_show(struct device *dev,493 struct device_attribute *devattr,494 char *buf)495{496 struct amc6821_data *data = dev_get_drvdata(dev);497 int ix = to_sensor_dev_attr_2(devattr)->index;498 int nr = to_sensor_dev_attr_2(devattr)->nr;499 u8 temps[3];500 int err;501 502 mutex_lock(&data->update_lock);503 err = amc6821_get_auto_point_temps(data->regmap, nr, temps);504 mutex_unlock(&data->update_lock);505 if (err)506 return err;507 508 return sysfs_emit(buf, "%d\n", temps[ix] * 1000);509}510 511static ssize_t pwm1_auto_point_pwm_show(struct device *dev,512 struct device_attribute *devattr,513 char *buf)514{515 struct amc6821_data *data = dev_get_drvdata(dev);516 int ix = to_sensor_dev_attr(devattr)->index;517 u32 val;518 int err;519 520 switch (ix) {521 case 0:522 val = 0;523 break;524 case 1:525 err = regmap_read(data->regmap, AMC6821_REG_DCY_LOW_TEMP, &val);526 if (err)527 return err;528 break;529 default:530 val = 255;531 break;532 }533 return sysfs_emit(buf, "%d\n", val);534}535 536/*537 * Set TEMP[0-4] (low temperature) and SLP[0-2] (slope) of local or remote538 * TEMP-FAN control register.539 *540 * Return 0 on success or negative error code.541 *542 * Channel 0: local, channel 1: remote543 */544static inline int set_slope_register(struct regmap *regmap, int channel, u8 *temps)545{546 u8 regval = FIELD_PREP(AMC6821_TEMP_LIMIT_MASK, temps[1] / 4);547 u8 tmp, dpwm;548 int err, dt;549 u32 pwm;550 551 err = regmap_read(regmap, AMC6821_REG_DCY_LOW_TEMP, &pwm);552 if (err)553 return err;554 555 dpwm = 255 - pwm;556 557 dt = temps[2] - temps[1];558 for (tmp = 4; tmp > 0; tmp--) {559 if (dt * (32 >> tmp) >= dpwm)560 break;561 }562 regval |= FIELD_PREP(AMC6821_TEMP_SLOPE_MASK, tmp);563 564 return regmap_write(regmap,565 channel ? AMC6821_REG_RTEMP_FAN_CTRL : AMC6821_REG_LTEMP_FAN_CTRL,566 regval);567}568 569static ssize_t temp_auto_point_temp_store(struct device *dev,570 struct device_attribute *attr,571 const char *buf, size_t count)572{573 struct amc6821_data *data = dev_get_drvdata(dev);574 int ix = to_sensor_dev_attr_2(attr)->index;575 int nr = to_sensor_dev_attr_2(attr)->nr;576 struct regmap *regmap = data->regmap;577 u8 temps[3], otemps[3];578 long val;579 int ret;580 581 ret = kstrtol(buf, 10, &val);582 if (ret)583 return ret;584 585 mutex_lock(&data->update_lock);586 587 ret = amc6821_get_auto_point_temps(data->regmap, nr, temps);588 if (ret)589 goto unlock;590 591 switch (ix) {592 case 0:593 /*594 * Passive cooling temperature. Range limit against low limit595 * of both channels.596 */597 ret = amc6821_get_auto_point_temps(data->regmap, 1 - nr, otemps);598 if (ret)599 goto unlock;600 val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 63000), 1000);601 val = clamp_val(val, 0, min(temps[1], otemps[1]));602 ret = regmap_write(regmap, AMC6821_REG_PSV_TEMP, val);603 break;604 case 1:605 /*606 * Low limit; must be between passive and high limit,607 * and not exceed 124. Step size is 4 degrees C.608 */609 val = clamp_val(val, DIV_ROUND_UP(temps[0], 4) * 4000, 124000);610 temps[1] = DIV_ROUND_CLOSEST(val, 4000) * 4;611 val = temps[1] / 4;612 /* Auto-adjust high limit if necessary */613 temps[2] = clamp_val(temps[2], temps[1] + 1, 255);614 ret = set_slope_register(regmap, nr, temps);615 break;616 case 2:617 /* high limit, must be higher than low limit */618 val = clamp_val(val, (temps[1] + 1) * 1000, 255000);619 temps[2] = DIV_ROUND_CLOSEST(val, 1000);620 ret = set_slope_register(regmap, nr, temps);621 break;622 default:623 ret = -EINVAL;624 break;625 }626unlock:627 mutex_unlock(&data->update_lock);628 return ret ? : count;629}630 631static ssize_t pwm1_auto_point_pwm_store(struct device *dev,632 struct device_attribute *attr,633 const char *buf, size_t count)634{635 struct amc6821_data *data = dev_get_drvdata(dev);636 struct regmap *regmap = data->regmap;637 int i, ret;638 u8 val;639 640 ret = kstrtou8(buf, 10, &val);641 if (ret)642 return ret;643 644 mutex_lock(&data->update_lock);645 ret = regmap_write(regmap, AMC6821_REG_DCY_LOW_TEMP, val);646 if (ret)647 goto unlock;648 649 for (i = 0; i < 2; i++) {650 u8 temps[3];651 652 ret = amc6821_get_auto_point_temps(regmap, i, temps);653 if (ret)654 break;655 ret = set_slope_register(regmap, i, temps);656 if (ret)657 break;658 }659unlock:660 mutex_unlock(&data->update_lock);661 return ret ? : count;662}663 664static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm1_auto_point_pwm, 0);665static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_pwm, pwm1_auto_point_pwm, 1);666static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point3_pwm, pwm1_auto_point_pwm, 2);667static SENSOR_DEVICE_ATTR_2_RO(temp1_auto_point1_temp, temp_auto_point_temp,668 0, 0);669static SENSOR_DEVICE_ATTR_2_RW(temp1_auto_point2_temp, temp_auto_point_temp,670 0, 1);671static SENSOR_DEVICE_ATTR_2_RW(temp1_auto_point3_temp, temp_auto_point_temp,672 0, 2);673 674static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point1_temp, temp_auto_point_temp,675 1, 0);676static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point2_temp, temp_auto_point_temp,677 1, 1);678static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point3_temp, temp_auto_point_temp,679 1, 2);680 681static struct attribute *amc6821_attrs[] = {682 &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,683 &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,684 &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,685 &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,686 &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,687 &sensor_dev_attr_temp1_auto_point3_temp.dev_attr.attr,688 &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,689 &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,690 &sensor_dev_attr_temp2_auto_point3_temp.dev_attr.attr,691 NULL692};693ATTRIBUTE_GROUPS(amc6821);694 695static int amc6821_read(struct device *dev, enum hwmon_sensor_types type,696 u32 attr, int channel, long *val)697{698 switch (type) {699 case hwmon_temp:700 return amc6821_temp_read(dev, attr, channel, val);701 case hwmon_fan:702 return amc6821_fan_read(dev, attr, val);703 case hwmon_pwm:704 return amc6821_pwm_read(dev, attr, val);705 default:706 return -EOPNOTSUPP;707 }708}709 710static int amc6821_write(struct device *dev, enum hwmon_sensor_types type,711 u32 attr, int channel, long val)712{713 switch (type) {714 case hwmon_temp:715 return amc6821_temp_write(dev, attr, channel, val);716 case hwmon_fan:717 return amc6821_fan_write(dev, attr, val);718 case hwmon_pwm:719 return amc6821_pwm_write(dev, attr, val);720 default:721 return -EOPNOTSUPP;722 }723}724 725static umode_t amc6821_is_visible(const void *data,726 enum hwmon_sensor_types type,727 u32 attr, int channel)728{729 switch (type) {730 case hwmon_temp:731 switch (attr) {732 case hwmon_temp_input:733 case hwmon_temp_min_alarm:734 case hwmon_temp_max_alarm:735 case hwmon_temp_crit_alarm:736 case hwmon_temp_fault:737 return 0444;738 case hwmon_temp_min:739 case hwmon_temp_max:740 case hwmon_temp_crit:741 return 0644;742 default:743 return 0;744 }745 case hwmon_fan:746 switch (attr) {747 case hwmon_fan_input:748 case hwmon_fan_fault:749 return 0444;750 case hwmon_fan_pulses:751 case hwmon_fan_min:752 case hwmon_fan_max:753 case hwmon_fan_target:754 return 0644;755 default:756 return 0;757 }758 case hwmon_pwm:759 switch (attr) {760 case hwmon_pwm_mode:761 case hwmon_pwm_enable:762 case hwmon_pwm_input:763 return 0644;764 case hwmon_pwm_auto_channels_temp:765 return 0444;766 default:767 return 0;768 }769 default:770 return 0;771 }772}773 774static const struct hwmon_channel_info * const amc6821_info[] = {775 HWMON_CHANNEL_INFO(temp,776 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |777 HWMON_T_CRIT | HWMON_T_MIN_ALARM |778 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,779 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |780 HWMON_T_CRIT | HWMON_T_MIN_ALARM |781 HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM |782 HWMON_T_FAULT),783 HWMON_CHANNEL_INFO(fan,784 HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_MAX |785 HWMON_F_TARGET | HWMON_F_PULSES | HWMON_F_FAULT),786 HWMON_CHANNEL_INFO(pwm,787 HWMON_PWM_INPUT | HWMON_PWM_ENABLE | HWMON_PWM_MODE |788 HWMON_PWM_AUTO_CHANNELS_TEMP),789 NULL790};791 792static const struct hwmon_ops amc6821_hwmon_ops = {793 .is_visible = amc6821_is_visible,794 .read = amc6821_read,795 .write = amc6821_write,796};797 798static const struct hwmon_chip_info amc6821_chip_info = {799 .ops = &amc6821_hwmon_ops,800 .info = amc6821_info,801};802 803/* Return 0 if detection is successful, -ENODEV otherwise */804static int amc6821_detect(struct i2c_client *client, struct i2c_board_info *info)805{806 struct i2c_adapter *adapter = client->adapter;807 int address = client->addr;808 int dev_id, comp_id;809 810 dev_dbg(&adapter->dev, "amc6821_detect called.\n");811 812 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {813 dev_dbg(&adapter->dev,814 "amc6821: I2C bus doesn't support byte mode, "815 "skipping.\n");816 return -ENODEV;817 }818 819 dev_id = i2c_smbus_read_byte_data(client, AMC6821_REG_DEV_ID);820 comp_id = i2c_smbus_read_byte_data(client, AMC6821_REG_COMP_ID);821 if (dev_id != 0x21 || comp_id != 0x49) {822 dev_dbg(&adapter->dev,823 "amc6821: detection failed at 0x%02x.\n",824 address);825 return -ENODEV;826 }827 828 /*829 * Bit 7 of the address register is ignored, so we can check the830 * ID registers again831 */832 dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID);833 comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID);834 if (dev_id != 0x21 || comp_id != 0x49) {835 dev_dbg(&adapter->dev,836 "amc6821: detection failed at 0x%02x.\n",837 address);838 return -ENODEV;839 }840 841 dev_info(&adapter->dev, "amc6821: chip found at 0x%02x.\n", address);842 strscpy(info->type, "amc6821", I2C_NAME_SIZE);843 844 return 0;845}846 847static int amc6821_init_client(struct amc6821_data *data)848{849 struct regmap *regmap = data->regmap;850 int err;851 852 if (init) {853 err = regmap_set_bits(regmap, AMC6821_REG_CONF4, AMC6821_CONF4_MODE);854 if (err)855 return err;856 err = regmap_clear_bits(regmap, AMC6821_REG_CONF3, AMC6821_CONF3_THERM_FAN_EN);857 if (err)858 return err;859 err = regmap_clear_bits(regmap, AMC6821_REG_CONF2,860 AMC6821_CONF2_RTFIE |861 AMC6821_CONF2_LTOIE |862 AMC6821_CONF2_RTOIE);863 if (err)864 return err;865 866 err = regmap_update_bits(regmap, AMC6821_REG_CONF1,867 AMC6821_CONF1_THERMOVIE | AMC6821_CONF1_FANIE |868 AMC6821_CONF1_START | AMC6821_CONF1_PWMINV,869 AMC6821_CONF1_START |870 (pwminv ? AMC6821_CONF1_PWMINV : 0));871 if (err)872 return err;873 }874 return 0;875}876 877static bool amc6821_volatile_reg(struct device *dev, unsigned int reg)878{879 switch (reg) {880 case AMC6821_REG_STAT1:881 case AMC6821_REG_STAT2:882 case AMC6821_REG_TEMP_LO:883 case AMC6821_REG_TDATA_LOW:884 case AMC6821_REG_LTEMP_HI:885 case AMC6821_REG_RTEMP_HI:886 case AMC6821_REG_TDATA_HI:887 return true;888 default:889 return false;890 }891}892 893static const struct regmap_config amc6821_regmap_config = {894 .reg_bits = 8,895 .val_bits = 8,896 .max_register = AMC6821_REG_CONF3,897 .volatile_reg = amc6821_volatile_reg,898 .cache_type = REGCACHE_MAPLE,899};900 901static int amc6821_probe(struct i2c_client *client)902{903 struct device *dev = &client->dev;904 struct amc6821_data *data;905 struct device *hwmon_dev;906 struct regmap *regmap;907 int err;908 909 data = devm_kzalloc(dev, sizeof(struct amc6821_data), GFP_KERNEL);910 if (!data)911 return -ENOMEM;912 913 regmap = devm_regmap_init_i2c(client, &amc6821_regmap_config);914 if (IS_ERR(regmap))915 return dev_err_probe(dev, PTR_ERR(regmap),916 "Failed to initialize regmap\n");917 data->regmap = regmap;918 919 err = amc6821_init_client(data);920 if (err)921 return err;922 923 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,924 data, &amc6821_chip_info,925 amc6821_groups);926 return PTR_ERR_OR_ZERO(hwmon_dev);927}928 929static const struct i2c_device_id amc6821_id[] = {930 { "amc6821", 0 },931 { }932};933 934MODULE_DEVICE_TABLE(i2c, amc6821_id);935 936static const struct of_device_id __maybe_unused amc6821_of_match[] = {937 {938 .compatible = "ti,amc6821",939 },940 { }941};942 943MODULE_DEVICE_TABLE(of, amc6821_of_match);944 945static struct i2c_driver amc6821_driver = {946 .class = I2C_CLASS_HWMON,947 .driver = {948 .name = "amc6821",949 .of_match_table = of_match_ptr(amc6821_of_match),950 },951 .probe = amc6821_probe,952 .id_table = amc6821_id,953 .detect = amc6821_detect,954 .address_list = normal_i2c,955};956 957module_i2c_driver(amc6821_driver);958 959MODULE_LICENSE("GPL");960MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>");961MODULE_DESCRIPTION("Texas Instruments amc6821 hwmon driver");962