Lines 55-60
Link Here
|
55 |
#include <linux/dmi.h> |
55 |
#include <linux/dmi.h> |
56 |
#include <linux/io.h> |
56 |
#include <linux/io.h> |
57 |
#include <linux/nospec.h> |
57 |
#include <linux/nospec.h> |
|
|
58 |
#include <linux/wmi.h> |
59 |
#include <linux/i2c.h> |
60 |
#include <linux/delay.h> |
58 |
#include "lm75.h" |
61 |
#include "lm75.h" |
59 |
|
62 |
|
60 |
#define USE_ALTERNATE |
63 |
#define USE_ALTERNATE |
Lines 132-162
MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
Link Here
|
132 |
#define SIO_ID_MASK 0xFFF8 |
135 |
#define SIO_ID_MASK 0xFFF8 |
133 |
|
136 |
|
134 |
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; |
137 |
enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 }; |
|
|
138 |
enum sensor_access { access_direct, access_asuswmi }; |
135 |
|
139 |
|
136 |
static inline void |
140 |
struct nct6775_sio_data { |
137 |
superio_outb(int ioreg, int reg, int val) |
141 |
int sioreg; |
|
|
142 |
int ld; |
143 |
enum kinds kind; |
144 |
enum sensor_access access; |
145 |
acpi_handle acpi_wmi_mutex; |
146 |
|
147 |
/* superio_() callbacks */ |
148 |
void (*sio_outb)(struct nct6775_sio_data *sio_data, int reg, int val); |
149 |
int (*sio_inb)(struct nct6775_sio_data *sio_data, int reg); |
150 |
void (*sio_select)(struct nct6775_sio_data *sio_data, int ld); |
151 |
int (*sio_enter)(struct nct6775_sio_data *sio_data); |
152 |
void (*sio_exit)(struct nct6775_sio_data *sio_data); |
153 |
}; |
154 |
|
155 |
#define ASUSWMI_MONITORING_GUID "466747A0-70EC-11DE-8A39-0800200C9A66" |
156 |
#define ASUSWMI_METHODID_RSIO 0x5253494F |
157 |
#define ASUSWMI_METHODID_WSIO 0x5753494F |
158 |
#define ASUSWMI_METHODID_RHWM 0x5248574D |
159 |
#define ASUSWMI_METHODID_WHWM 0x5748574D |
160 |
#define ASUSWMI_UNSUPPORTED_METHOD 0xFFFFFFFE |
161 |
/* Wait for up to 0.5 s to acquire the lock */ |
162 |
#define ASUSWMI_LOCK_TIMEOUT_MS 500 |
163 |
|
164 |
static int nct6775_asuswmi_evaluate_method(u32 method_id, u8 bank, u8 reg, u8 val, u32 *retval) |
165 |
{ |
166 |
#if IS_ENABLED(CONFIG_ACPI_WMI) |
167 |
u32 args = bank | (reg << 8) | (val << 16); |
168 |
struct acpi_buffer input = { (acpi_size) sizeof(args), &args }; |
169 |
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
170 |
acpi_status status; |
171 |
union acpi_object *obj; |
172 |
u32 tmp = ASUSWMI_UNSUPPORTED_METHOD; |
173 |
|
174 |
status = wmi_evaluate_method(ASUSWMI_MONITORING_GUID, 0, |
175 |
method_id, &input, &output); |
176 |
|
177 |
if (ACPI_FAILURE(status)) |
178 |
return -EIO; |
179 |
|
180 |
obj = output.pointer; |
181 |
if (obj && obj->type == ACPI_TYPE_INTEGER) |
182 |
tmp = obj->integer.value; |
183 |
|
184 |
if (retval) |
185 |
*retval = tmp; |
186 |
|
187 |
kfree(obj); |
188 |
|
189 |
if (tmp == ASUSWMI_UNSUPPORTED_METHOD) |
190 |
return -ENODEV; |
191 |
return 0; |
192 |
#else |
193 |
return -EOPNOTSUPP; |
194 |
#endif |
195 |
} |
196 |
|
197 |
static inline int nct6775_asuswmi_write(u8 bank, u8 reg, u8 val) |
198 |
{ |
199 |
return nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WHWM, bank, |
200 |
reg, val, NULL); |
201 |
} |
202 |
|
203 |
static inline int nct6775_asuswmi_read(u8 bank, u8 reg, u8 *val) |
204 |
{ |
205 |
u32 ret, tmp = 0; |
206 |
|
207 |
ret = nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RHWM, bank, |
208 |
reg, 0, &tmp); |
209 |
*val = tmp; |
210 |
return ret; |
211 |
} |
212 |
|
213 |
static int superio_wmi_inb(struct nct6775_sio_data *sio_data, int reg) |
214 |
{ |
215 |
int tmp = 0; |
216 |
|
217 |
nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_RSIO, sio_data->ld, |
218 |
reg, 0, &tmp); |
219 |
return tmp; |
220 |
} |
221 |
|
222 |
static void superio_wmi_outb(struct nct6775_sio_data *sio_data, int reg, int val) |
223 |
{ |
224 |
nct6775_asuswmi_evaluate_method(ASUSWMI_METHODID_WSIO, sio_data->ld, |
225 |
reg, val, NULL); |
226 |
} |
227 |
|
228 |
static void superio_wmi_select(struct nct6775_sio_data *sio_data, int ld) |
229 |
{ |
230 |
sio_data->ld = ld; |
231 |
} |
232 |
|
233 |
static int superio_wmi_enter(struct nct6775_sio_data *sio_data) |
234 |
{ |
235 |
return 0; |
236 |
} |
237 |
|
238 |
static void superio_wmi_exit(struct nct6775_sio_data *sio_data) |
239 |
{ |
240 |
} |
241 |
|
242 |
static void superio_outb(struct nct6775_sio_data *sio_data, int reg, int val) |
138 |
{ |
243 |
{ |
|
|
244 |
int ioreg = sio_data->sioreg; |
245 |
|
139 |
outb(reg, ioreg); |
246 |
outb(reg, ioreg); |
140 |
outb(val, ioreg + 1); |
247 |
outb(val, ioreg + 1); |
141 |
} |
248 |
} |
142 |
|
249 |
|
143 |
static inline int |
250 |
static int superio_inb(struct nct6775_sio_data *sio_data, int reg) |
144 |
superio_inb(int ioreg, int reg) |
|
|
145 |
{ |
251 |
{ |
|
|
252 |
int ioreg = sio_data->sioreg; |
253 |
|
146 |
outb(reg, ioreg); |
254 |
outb(reg, ioreg); |
147 |
return inb(ioreg + 1); |
255 |
return inb(ioreg + 1); |
148 |
} |
256 |
} |
149 |
|
257 |
|
150 |
static inline void |
258 |
static void superio_select(struct nct6775_sio_data *sio_data, int ld) |
151 |
superio_select(int ioreg, int ld) |
|
|
152 |
{ |
259 |
{ |
|
|
260 |
int ioreg = sio_data->sioreg; |
261 |
|
153 |
outb(SIO_REG_LDSEL, ioreg); |
262 |
outb(SIO_REG_LDSEL, ioreg); |
154 |
outb(ld, ioreg + 1); |
263 |
outb(ld, ioreg + 1); |
155 |
} |
264 |
} |
156 |
|
265 |
|
157 |
static inline int |
266 |
static int superio_enter(struct nct6775_sio_data *sio_data) |
158 |
superio_enter(int ioreg) |
|
|
159 |
{ |
267 |
{ |
|
|
268 |
int ioreg = sio_data->sioreg; |
269 |
|
160 |
/* |
270 |
/* |
161 |
* Try to reserve <ioreg> and <ioreg + 1> for exclusive access. |
271 |
* Try to reserve <ioreg> and <ioreg + 1> for exclusive access. |
162 |
*/ |
272 |
*/ |
Lines 169-177
superio_enter(int ioreg)
Link Here
|
169 |
return 0; |
279 |
return 0; |
170 |
} |
280 |
} |
171 |
|
281 |
|
172 |
static inline void |
282 |
static void superio_exit(struct nct6775_sio_data *sio_data) |
173 |
superio_exit(int ioreg) |
|
|
174 |
{ |
283 |
{ |
|
|
284 |
int ioreg = sio_data->sioreg; |
285 |
|
175 |
outb(0xaa, ioreg); |
286 |
outb(0xaa, ioreg); |
176 |
outb(0x02, ioreg); |
287 |
outb(0x02, ioreg); |
177 |
outb(0x02, ioreg + 1); |
288 |
outb(0x02, ioreg + 1); |
Lines 190-195
superio_exit(int ioreg)
Link Here
|
190 |
|
301 |
|
191 |
#define NCT6775_REG_BANK 0x4E |
302 |
#define NCT6775_REG_BANK 0x4E |
192 |
#define NCT6775_REG_CONFIG 0x40 |
303 |
#define NCT6775_REG_CONFIG 0x40 |
|
|
304 |
#define NCT6775_PORT_CHIPID 0x58 |
193 |
|
305 |
|
194 |
/* |
306 |
/* |
195 |
* Not currently used: |
307 |
* Not currently used: |
Lines 1136-1142
struct nct6775_data {
Link Here
|
1136 |
unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); |
1248 |
unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg); |
1137 |
unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); |
1249 |
unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg); |
1138 |
|
1250 |
|
1139 |
struct mutex update_lock; |
1251 |
union { |
|
|
1252 |
struct mutex update_lock; /* non ACPI lock */ |
1253 |
acpi_handle acpi_wmi_mutex; /* ACPI lock */ |
1254 |
} mlock; |
1255 |
|
1140 |
bool valid; /* true if following fields are valid */ |
1256 |
bool valid; /* true if following fields are valid */ |
1141 |
unsigned long last_updated; /* In jiffies */ |
1257 |
unsigned long last_updated; /* In jiffies */ |
1142 |
|
1258 |
|
Lines 1215-1225
struct nct6775_data {
Link Here
|
1215 |
u8 fandiv1; |
1331 |
u8 fandiv1; |
1216 |
u8 fandiv2; |
1332 |
u8 fandiv2; |
1217 |
u8 sio_reg_enable; |
1333 |
u8 sio_reg_enable; |
1218 |
}; |
|
|
1219 |
|
1334 |
|
1220 |
struct nct6775_sio_data { |
1335 |
/* ASUS boards specific i2c connected to nct6775 */ |
1221 |
int sioreg; |
1336 |
struct i2c_adapter *i2c_adapter; |
1222 |
enum kinds kind; |
1337 |
|
|
|
1338 |
/* nct6775_*() callbacks */ |
1339 |
u16 (*read_value)(struct nct6775_data *data, u16 reg); |
1340 |
int (*write_value)(struct nct6775_data *data, u16 reg, u16 value); |
1341 |
int (*lock)(struct nct6775_data *data); |
1342 |
void (*unlock)(struct nct6775_data *data, struct device *dev); |
1223 |
}; |
1343 |
}; |
1224 |
|
1344 |
|
1225 |
struct sensor_device_template { |
1345 |
struct sensor_device_template { |
Lines 1407-1412
static bool is_word_sized(struct nct6775_data *data, u16 reg)
Link Here
|
1407 |
return false; |
1527 |
return false; |
1408 |
} |
1528 |
} |
1409 |
|
1529 |
|
|
|
1530 |
static inline void nct6775_wmi_set_bank(struct nct6775_data *data, u16 reg) |
1531 |
{ |
1532 |
u8 bank = reg >> 8; |
1533 |
|
1534 |
data->bank = bank; |
1535 |
} |
1536 |
|
1537 |
static u16 nct6775_wmi_read_value(struct nct6775_data *data, u16 reg) |
1538 |
{ |
1539 |
int res, err, word_sized = is_word_sized(data, reg); |
1540 |
u8 tmp = 0; |
1541 |
|
1542 |
nct6775_wmi_set_bank(data, reg); |
1543 |
|
1544 |
err = nct6775_asuswmi_read(data->bank, reg, &tmp); |
1545 |
if (err) |
1546 |
return 0; |
1547 |
|
1548 |
res = tmp; |
1549 |
if (word_sized) { |
1550 |
err = nct6775_asuswmi_read(data->bank, (reg & 0xff) + 1, &tmp); |
1551 |
if (err) |
1552 |
return 0; |
1553 |
|
1554 |
res = (res << 8) + tmp; |
1555 |
} |
1556 |
return res; |
1557 |
} |
1558 |
|
1559 |
static int nct6775_wmi_write_value(struct nct6775_data *data, u16 reg, u16 value) |
1560 |
{ |
1561 |
int res, word_sized = is_word_sized(data, reg); |
1562 |
|
1563 |
nct6775_wmi_set_bank(data, reg); |
1564 |
|
1565 |
if (word_sized) { |
1566 |
res = nct6775_asuswmi_write(data->bank, reg & 0xff, value >> 8); |
1567 |
if (res) |
1568 |
return res; |
1569 |
|
1570 |
res = nct6775_asuswmi_write(data->bank, (reg & 0xff) + 1, value); |
1571 |
} else { |
1572 |
res = nct6775_asuswmi_write(data->bank, reg & 0xff, value); |
1573 |
} |
1574 |
|
1575 |
return res; |
1576 |
} |
1577 |
|
1578 |
static int nct6775_wmi_lock(struct nct6775_data *data) |
1579 |
{ |
1580 |
acpi_status status; |
1581 |
|
1582 |
status = acpi_acquire_mutex(data->mlock.acpi_wmi_mutex, NULL, ASUSWMI_LOCK_TIMEOUT_MS); |
1583 |
if (ACPI_FAILURE(status)) |
1584 |
return -EIO; |
1585 |
|
1586 |
return 0; |
1587 |
} |
1588 |
|
1589 |
static void nct6775_wmi_unlock(struct nct6775_data *data, struct device *dev) |
1590 |
{ |
1591 |
acpi_status status; |
1592 |
|
1593 |
status = acpi_release_mutex(data->mlock.acpi_wmi_mutex, NULL); |
1594 |
if (ACPI_FAILURE(status)) |
1595 |
dev_err(dev, "Failed to release mutex."); |
1596 |
} |
1597 |
|
1410 |
/* |
1598 |
/* |
1411 |
* On older chips, only registers 0x50-0x5f are banked. |
1599 |
* On older chips, only registers 0x50-0x5f are banked. |
1412 |
* On more recent chips, all registers are banked. |
1600 |
* On more recent chips, all registers are banked. |
Lines 1459-1465
static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
Link Here
|
1459 |
{ |
1647 |
{ |
1460 |
u16 res; |
1648 |
u16 res; |
1461 |
|
1649 |
|
1462 |
res = nct6775_read_value(data, reg); |
1650 |
res = data->read_value(data, reg); |
1463 |
if (!is_word_sized(data, reg)) |
1651 |
if (!is_word_sized(data, reg)) |
1464 |
res <<= 8; |
1652 |
res <<= 8; |
1465 |
|
1653 |
|
Lines 1470-1476
static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
Link Here
|
1470 |
{ |
1658 |
{ |
1471 |
if (!is_word_sized(data, reg)) |
1659 |
if (!is_word_sized(data, reg)) |
1472 |
value >>= 8; |
1660 |
value >>= 8; |
1473 |
return nct6775_write_value(data, reg, value); |
1661 |
return data->write_value(data, reg, value); |
1474 |
} |
1662 |
} |
1475 |
|
1663 |
|
1476 |
/* This function assumes that the caller holds data->update_lock */ |
1664 |
/* This function assumes that the caller holds data->update_lock */ |
Lines 1480-1503
static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
Link Here
|
1480 |
|
1668 |
|
1481 |
switch (nr) { |
1669 |
switch (nr) { |
1482 |
case 0: |
1670 |
case 0: |
1483 |
reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70) |
1671 |
reg = (data->read_value(data, NCT6775_REG_FANDIV1) & 0x70) |
1484 |
| (data->fan_div[0] & 0x7); |
1672 |
| (data->fan_div[0] & 0x7); |
1485 |
nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); |
1673 |
data->write_value(data, NCT6775_REG_FANDIV1, reg); |
1486 |
break; |
1674 |
break; |
1487 |
case 1: |
1675 |
case 1: |
1488 |
reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7) |
1676 |
reg = (data->read_value(data, NCT6775_REG_FANDIV1) & 0x7) |
1489 |
| ((data->fan_div[1] << 4) & 0x70); |
1677 |
| ((data->fan_div[1] << 4) & 0x70); |
1490 |
nct6775_write_value(data, NCT6775_REG_FANDIV1, reg); |
1678 |
data->write_value(data, NCT6775_REG_FANDIV1, reg); |
1491 |
break; |
1679 |
break; |
1492 |
case 2: |
1680 |
case 2: |
1493 |
reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70) |
1681 |
reg = (data->read_value(data, NCT6775_REG_FANDIV2) & 0x70) |
1494 |
| (data->fan_div[2] & 0x7); |
1682 |
| (data->fan_div[2] & 0x7); |
1495 |
nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); |
1683 |
data->write_value(data, NCT6775_REG_FANDIV2, reg); |
1496 |
break; |
1684 |
break; |
1497 |
case 3: |
1685 |
case 3: |
1498 |
reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7) |
1686 |
reg = (data->read_value(data, NCT6775_REG_FANDIV2) & 0x7) |
1499 |
| ((data->fan_div[3] << 4) & 0x70); |
1687 |
| ((data->fan_div[3] << 4) & 0x70); |
1500 |
nct6775_write_value(data, NCT6775_REG_FANDIV2, reg); |
1688 |
data->write_value(data, NCT6775_REG_FANDIV2, reg); |
1501 |
break; |
1689 |
break; |
1502 |
} |
1690 |
} |
1503 |
} |
1691 |
} |
Lines 1512-1521
static void nct6775_update_fan_div(struct nct6775_data *data)
Link Here
|
1512 |
{ |
1700 |
{ |
1513 |
u8 i; |
1701 |
u8 i; |
1514 |
|
1702 |
|
1515 |
i = nct6775_read_value(data, NCT6775_REG_FANDIV1); |
1703 |
i = data->read_value(data, NCT6775_REG_FANDIV1); |
1516 |
data->fan_div[0] = i & 0x7; |
1704 |
data->fan_div[0] = i & 0x7; |
1517 |
data->fan_div[1] = (i & 0x70) >> 4; |
1705 |
data->fan_div[1] = (i & 0x70) >> 4; |
1518 |
i = nct6775_read_value(data, NCT6775_REG_FANDIV2); |
1706 |
i = data->read_value(data, NCT6775_REG_FANDIV2); |
1519 |
data->fan_div[2] = i & 0x7; |
1707 |
data->fan_div[2] = i & 0x7; |
1520 |
if (data->has_fan & BIT(3)) |
1708 |
if (data->has_fan & BIT(3)) |
1521 |
data->fan_div[3] = (i & 0x70) >> 4; |
1709 |
data->fan_div[3] = (i & 0x70) >> 4; |
Lines 1563-1573
static void nct6775_init_fan_common(struct device *dev,
Link Here
|
1563 |
*/ |
1751 |
*/ |
1564 |
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { |
1752 |
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { |
1565 |
if (data->has_fan_min & BIT(i)) { |
1753 |
if (data->has_fan_min & BIT(i)) { |
1566 |
reg = nct6775_read_value(data, data->REG_FAN_MIN[i]); |
1754 |
reg = data->read_value(data, data->REG_FAN_MIN[i]); |
1567 |
if (!reg) |
1755 |
if (!reg) |
1568 |
nct6775_write_value(data, data->REG_FAN_MIN[i], |
1756 |
data->write_value(data, data->REG_FAN_MIN[i], |
1569 |
data->has_fan_div ? 0xff |
1757 |
data->has_fan_div ? 0xff |
1570 |
: 0xff1f); |
1758 |
: 0xff1f); |
1571 |
} |
1759 |
} |
1572 |
} |
1760 |
} |
1573 |
} |
1761 |
} |
Lines 1611-1618
static void nct6775_select_fan_div(struct device *dev,
Link Here
|
1611 |
} |
1799 |
} |
1612 |
if (fan_min != data->fan_min[nr]) { |
1800 |
if (fan_min != data->fan_min[nr]) { |
1613 |
data->fan_min[nr] = fan_min; |
1801 |
data->fan_min[nr] = fan_min; |
1614 |
nct6775_write_value(data, data->REG_FAN_MIN[nr], |
1802 |
data->write_value(data, data->REG_FAN_MIN[nr], |
1615 |
fan_min); |
1803 |
fan_min); |
1616 |
} |
1804 |
} |
1617 |
} |
1805 |
} |
1618 |
data->fan_div[nr] = fan_div; |
1806 |
data->fan_div[nr] = fan_div; |
Lines 1632-1647
static void nct6775_update_pwm(struct device *dev)
Link Here
|
1632 |
continue; |
1820 |
continue; |
1633 |
|
1821 |
|
1634 |
duty_is_dc = data->REG_PWM_MODE[i] && |
1822 |
duty_is_dc = data->REG_PWM_MODE[i] && |
1635 |
(nct6775_read_value(data, data->REG_PWM_MODE[i]) |
1823 |
(data->read_value(data, data->REG_PWM_MODE[i]) |
1636 |
& data->PWM_MODE_MASK[i]); |
1824 |
& data->PWM_MODE_MASK[i]); |
1637 |
data->pwm_mode[i] = !duty_is_dc; |
1825 |
data->pwm_mode[i] = !duty_is_dc; |
1638 |
|
1826 |
|
1639 |
fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]); |
1827 |
fanmodecfg = data->read_value(data, data->REG_FAN_MODE[i]); |
1640 |
for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) { |
1828 |
for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) { |
1641 |
if (data->REG_PWM[j] && data->REG_PWM[j][i]) { |
1829 |
if (data->REG_PWM[j] && data->REG_PWM[j][i]) { |
1642 |
data->pwm[j][i] |
1830 |
data->pwm[j][i] = data->read_value(data, |
1643 |
= nct6775_read_value(data, |
1831 |
data->REG_PWM[j][i]); |
1644 |
data->REG_PWM[j][i]); |
|
|
1645 |
} |
1832 |
} |
1646 |
} |
1833 |
} |
1647 |
|
1834 |
|
Lines 1656-1672
static void nct6775_update_pwm(struct device *dev)
Link Here
|
1656 |
u8 t = fanmodecfg & 0x0f; |
1843 |
u8 t = fanmodecfg & 0x0f; |
1657 |
|
1844 |
|
1658 |
if (data->REG_TOLERANCE_H) { |
1845 |
if (data->REG_TOLERANCE_H) { |
1659 |
t |= (nct6775_read_value(data, |
1846 |
t |= (data->read_value(data, |
1660 |
data->REG_TOLERANCE_H[i]) & 0x70) >> 1; |
1847 |
data->REG_TOLERANCE_H[i]) & 0x70) >> 1; |
1661 |
} |
1848 |
} |
1662 |
data->target_speed_tolerance[i] = t; |
1849 |
data->target_speed_tolerance[i] = t; |
1663 |
} |
1850 |
} |
1664 |
|
1851 |
|
1665 |
data->temp_tolerance[1][i] = |
1852 |
data->temp_tolerance[1][i] = |
1666 |
nct6775_read_value(data, |
1853 |
data->read_value(data, |
1667 |
data->REG_CRITICAL_TEMP_TOLERANCE[i]); |
1854 |
data->REG_CRITICAL_TEMP_TOLERANCE[i]); |
1668 |
|
1855 |
|
1669 |
reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]); |
1856 |
reg = data->read_value(data, data->REG_TEMP_SEL[i]); |
1670 |
data->pwm_temp_sel[i] = reg & 0x1f; |
1857 |
data->pwm_temp_sel[i] = reg & 0x1f; |
1671 |
/* If fan can stop, report floor as 0 */ |
1858 |
/* If fan can stop, report floor as 0 */ |
1672 |
if (reg & 0x80) |
1859 |
if (reg & 0x80) |
Lines 1675-1681
static void nct6775_update_pwm(struct device *dev)
Link Here
|
1675 |
if (!data->REG_WEIGHT_TEMP_SEL[i]) |
1862 |
if (!data->REG_WEIGHT_TEMP_SEL[i]) |
1676 |
continue; |
1863 |
continue; |
1677 |
|
1864 |
|
1678 |
reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]); |
1865 |
reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[i]); |
1679 |
data->pwm_weight_temp_sel[i] = reg & 0x1f; |
1866 |
data->pwm_weight_temp_sel[i] = reg & 0x1f; |
1680 |
/* If weight is disabled, report weight source as 0 */ |
1867 |
/* If weight is disabled, report weight source as 0 */ |
1681 |
if (!(reg & 0x80)) |
1868 |
if (!(reg & 0x80)) |
Lines 1683-1691
static void nct6775_update_pwm(struct device *dev)
Link Here
|
1683 |
|
1870 |
|
1684 |
/* Weight temp data */ |
1871 |
/* Weight temp data */ |
1685 |
for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) { |
1872 |
for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) { |
1686 |
data->weight_temp[j][i] |
1873 |
data->weight_temp[j][i] = data->read_value(data, |
1687 |
= nct6775_read_value(data, |
1874 |
data->REG_WEIGHT_TEMP[j][i]); |
1688 |
data->REG_WEIGHT_TEMP[j][i]); |
|
|
1689 |
} |
1875 |
} |
1690 |
} |
1876 |
} |
1691 |
} |
1877 |
} |
Lines 1703-1712
static void nct6775_update_pwm_limits(struct device *dev)
Link Here
|
1703 |
|
1889 |
|
1704 |
for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) { |
1890 |
for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) { |
1705 |
data->fan_time[j][i] = |
1891 |
data->fan_time[j][i] = |
1706 |
nct6775_read_value(data, data->REG_FAN_TIME[j][i]); |
1892 |
data->read_value(data, data->REG_FAN_TIME[j][i]); |
1707 |
} |
1893 |
} |
1708 |
|
1894 |
|
1709 |
reg_t = nct6775_read_value(data, data->REG_TARGET[i]); |
1895 |
reg_t = data->read_value(data, data->REG_TARGET[i]); |
1710 |
/* Update only in matching mode or if never updated */ |
1896 |
/* Update only in matching mode or if never updated */ |
1711 |
if (!data->target_temp[i] || |
1897 |
if (!data->target_temp[i] || |
1712 |
data->pwm_enable[i] == thermal_cruise) |
1898 |
data->pwm_enable[i] == thermal_cruise) |
Lines 1714-1720
static void nct6775_update_pwm_limits(struct device *dev)
Link Here
|
1714 |
if (!data->target_speed[i] || |
1900 |
if (!data->target_speed[i] || |
1715 |
data->pwm_enable[i] == speed_cruise) { |
1901 |
data->pwm_enable[i] == speed_cruise) { |
1716 |
if (data->REG_TOLERANCE_H) { |
1902 |
if (data->REG_TOLERANCE_H) { |
1717 |
reg_t |= (nct6775_read_value(data, |
1903 |
reg_t |= (data->read_value(data, |
1718 |
data->REG_TOLERANCE_H[i]) & 0x0f) << 8; |
1904 |
data->REG_TOLERANCE_H[i]) & 0x0f) << 8; |
1719 |
} |
1905 |
} |
1720 |
data->target_speed[i] = reg_t; |
1906 |
data->target_speed[i] = reg_t; |
Lines 1722-1742
static void nct6775_update_pwm_limits(struct device *dev)
Link Here
|
1722 |
|
1908 |
|
1723 |
for (j = 0; j < data->auto_pwm_num; j++) { |
1909 |
for (j = 0; j < data->auto_pwm_num; j++) { |
1724 |
data->auto_pwm[i][j] = |
1910 |
data->auto_pwm[i][j] = |
1725 |
nct6775_read_value(data, |
1911 |
data->read_value(data, |
1726 |
NCT6775_AUTO_PWM(data, i, j)); |
1912 |
NCT6775_AUTO_PWM(data, i, j)); |
1727 |
data->auto_temp[i][j] = |
1913 |
data->auto_temp[i][j] = |
1728 |
nct6775_read_value(data, |
1914 |
data->read_value(data, |
1729 |
NCT6775_AUTO_TEMP(data, i, j)); |
1915 |
NCT6775_AUTO_TEMP(data, i, j)); |
1730 |
} |
1916 |
} |
1731 |
|
1917 |
|
1732 |
/* critical auto_pwm temperature data */ |
1918 |
/* critical auto_pwm temperature data */ |
1733 |
data->auto_temp[i][data->auto_pwm_num] = |
1919 |
data->auto_temp[i][data->auto_pwm_num] = |
1734 |
nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]); |
1920 |
data->read_value(data, data->REG_CRITICAL_TEMP[i]); |
1735 |
|
1921 |
|
1736 |
switch (data->kind) { |
1922 |
switch (data->kind) { |
1737 |
case nct6775: |
1923 |
case nct6775: |
1738 |
reg = nct6775_read_value(data, |
1924 |
reg = data->read_value(data, |
1739 |
NCT6775_REG_CRITICAL_ENAB[i]); |
1925 |
NCT6775_REG_CRITICAL_ENAB[i]); |
1740 |
data->auto_pwm[i][data->auto_pwm_num] = |
1926 |
data->auto_pwm[i][data->auto_pwm_num] = |
1741 |
(reg & 0x02) ? 0xff : 0x00; |
1927 |
(reg & 0x02) ? 0xff : 0x00; |
1742 |
break; |
1928 |
break; |
Lines 1753-1762
static void nct6775_update_pwm_limits(struct device *dev)
Link Here
|
1753 |
case nct6796: |
1939 |
case nct6796: |
1754 |
case nct6797: |
1940 |
case nct6797: |
1755 |
case nct6798: |
1941 |
case nct6798: |
1756 |
reg = nct6775_read_value(data, |
1942 |
reg = data->read_value(data, |
1757 |
data->REG_CRITICAL_PWM_ENABLE[i]); |
1943 |
data->REG_CRITICAL_PWM_ENABLE[i]); |
1758 |
if (reg & data->CRITICAL_PWM_ENABLE_MASK) |
1944 |
if (reg & data->CRITICAL_PWM_ENABLE_MASK) |
1759 |
reg = nct6775_read_value(data, |
1945 |
reg = data->read_value(data, |
1760 |
data->REG_CRITICAL_PWM[i]); |
1946 |
data->REG_CRITICAL_PWM[i]); |
1761 |
else |
1947 |
else |
1762 |
reg = 0xff; |
1948 |
reg = 0xff; |
Lines 1766-1777
static void nct6775_update_pwm_limits(struct device *dev)
Link Here
|
1766 |
} |
1952 |
} |
1767 |
} |
1953 |
} |
1768 |
|
1954 |
|
|
|
1955 |
static int nct6775_lock(struct nct6775_data *data) |
1956 |
{ |
1957 |
mutex_lock(&data->mlock.update_lock); |
1958 |
|
1959 |
return 0; |
1960 |
} |
1961 |
|
1962 |
static void nct6775_unlock(struct nct6775_data *data, struct device *dev) |
1963 |
{ |
1964 |
mutex_unlock(&data->mlock.update_lock); |
1965 |
} |
1966 |
|
1769 |
static struct nct6775_data *nct6775_update_device(struct device *dev) |
1967 |
static struct nct6775_data *nct6775_update_device(struct device *dev) |
1770 |
{ |
1968 |
{ |
1771 |
struct nct6775_data *data = dev_get_drvdata(dev); |
1969 |
struct nct6775_data *data = dev_get_drvdata(dev); |
1772 |
int i, j; |
1970 |
int i, j, err; |
1773 |
|
1971 |
|
1774 |
mutex_lock(&data->update_lock); |
1972 |
err = data->lock(data); |
|
|
1973 |
if (err) |
1974 |
return data; |
1775 |
|
1975 |
|
1776 |
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
1976 |
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) |
1777 |
|| !data->valid) { |
1977 |
|| !data->valid) { |
Lines 1783-1793
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1783 |
if (!(data->have_in & BIT(i))) |
1983 |
if (!(data->have_in & BIT(i))) |
1784 |
continue; |
1984 |
continue; |
1785 |
|
1985 |
|
1786 |
data->in[i][0] = nct6775_read_value(data, |
1986 |
data->in[i][0] = data->read_value(data, |
1787 |
data->REG_VIN[i]); |
1987 |
data->REG_VIN[i]); |
1788 |
data->in[i][1] = nct6775_read_value(data, |
1988 |
data->in[i][1] = data->read_value(data, |
1789 |
data->REG_IN_MINMAX[0][i]); |
1989 |
data->REG_IN_MINMAX[0][i]); |
1790 |
data->in[i][2] = nct6775_read_value(data, |
1990 |
data->in[i][2] = data->read_value(data, |
1791 |
data->REG_IN_MINMAX[1][i]); |
1991 |
data->REG_IN_MINMAX[1][i]); |
1792 |
} |
1992 |
} |
1793 |
|
1993 |
|
Lines 1798-1815
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1798 |
if (!(data->has_fan & BIT(i))) |
1998 |
if (!(data->has_fan & BIT(i))) |
1799 |
continue; |
1999 |
continue; |
1800 |
|
2000 |
|
1801 |
reg = nct6775_read_value(data, data->REG_FAN[i]); |
2001 |
reg = data->read_value(data, data->REG_FAN[i]); |
1802 |
data->rpm[i] = data->fan_from_reg(reg, |
2002 |
data->rpm[i] = data->fan_from_reg(reg, |
1803 |
data->fan_div[i]); |
2003 |
data->fan_div[i]); |
1804 |
|
2004 |
|
1805 |
if (data->has_fan_min & BIT(i)) |
2005 |
if (data->has_fan_min & BIT(i)) |
1806 |
data->fan_min[i] = nct6775_read_value(data, |
2006 |
data->fan_min[i] = data->read_value(data, |
1807 |
data->REG_FAN_MIN[i]); |
2007 |
data->REG_FAN_MIN[i]); |
1808 |
|
2008 |
|
1809 |
if (data->REG_FAN_PULSES[i]) { |
2009 |
if (data->REG_FAN_PULSES[i]) { |
1810 |
data->fan_pulses[i] = |
2010 |
data->fan_pulses[i] = |
1811 |
(nct6775_read_value(data, |
2011 |
(data->read_value(data, |
1812 |
data->REG_FAN_PULSES[i]) |
2012 |
data->REG_FAN_PULSES[i]) |
1813 |
>> data->FAN_PULSE_SHIFT[i]) & 0x03; |
2013 |
>> data->FAN_PULSE_SHIFT[i]) & 0x03; |
1814 |
} |
2014 |
} |
1815 |
|
2015 |
|
Lines 1825-1839
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1825 |
continue; |
2025 |
continue; |
1826 |
for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) { |
2026 |
for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) { |
1827 |
if (data->reg_temp[j][i]) |
2027 |
if (data->reg_temp[j][i]) |
1828 |
data->temp[j][i] |
2028 |
data->temp[j][i] = nct6775_read_temp(data, |
1829 |
= nct6775_read_temp(data, |
2029 |
data->reg_temp[j][i]); |
1830 |
data->reg_temp[j][i]); |
|
|
1831 |
} |
2030 |
} |
1832 |
if (i >= NUM_TEMP_FIXED || |
2031 |
if (i >= NUM_TEMP_FIXED || |
1833 |
!(data->have_temp_fixed & BIT(i))) |
2032 |
!(data->have_temp_fixed & BIT(i))) |
1834 |
continue; |
2033 |
continue; |
1835 |
data->temp_offset[i] |
2034 |
data->temp_offset[i] = data->read_value(data, |
1836 |
= nct6775_read_value(data, data->REG_TEMP_OFFSET[i]); |
2035 |
data->REG_TEMP_OFFSET[i]); |
1837 |
} |
2036 |
} |
1838 |
|
2037 |
|
1839 |
data->alarms = 0; |
2038 |
data->alarms = 0; |
Lines 1842-1848
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1842 |
|
2041 |
|
1843 |
if (!data->REG_ALARM[i]) |
2042 |
if (!data->REG_ALARM[i]) |
1844 |
continue; |
2043 |
continue; |
1845 |
alarm = nct6775_read_value(data, data->REG_ALARM[i]); |
2044 |
alarm = data->read_value(data, data->REG_ALARM[i]); |
1846 |
data->alarms |= ((u64)alarm) << (i << 3); |
2045 |
data->alarms |= ((u64)alarm) << (i << 3); |
1847 |
} |
2046 |
} |
1848 |
|
2047 |
|
Lines 1852-1858
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1852 |
|
2051 |
|
1853 |
if (!data->REG_BEEP[i]) |
2052 |
if (!data->REG_BEEP[i]) |
1854 |
continue; |
2053 |
continue; |
1855 |
beep = nct6775_read_value(data, data->REG_BEEP[i]); |
2054 |
beep = data->read_value(data, data->REG_BEEP[i]); |
1856 |
data->beeps |= ((u64)beep) << (i << 3); |
2055 |
data->beeps |= ((u64)beep) << (i << 3); |
1857 |
} |
2056 |
} |
1858 |
|
2057 |
|
Lines 1860-1866
static struct nct6775_data *nct6775_update_device(struct device *dev)
Link Here
|
1860 |
data->valid = true; |
2059 |
data->valid = true; |
1861 |
} |
2060 |
} |
1862 |
|
2061 |
|
1863 |
mutex_unlock(&data->update_lock); |
2062 |
data->unlock(data, dev); |
1864 |
return data; |
2063 |
return data; |
1865 |
} |
2064 |
} |
1866 |
|
2065 |
|
Lines 1892-1902
store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
Link Here
|
1892 |
err = kstrtoul(buf, 10, &val); |
2091 |
err = kstrtoul(buf, 10, &val); |
1893 |
if (err < 0) |
2092 |
if (err < 0) |
1894 |
return err; |
2093 |
return err; |
1895 |
mutex_lock(&data->update_lock); |
2094 |
|
|
|
2095 |
err = data->lock(data); |
2096 |
if (err) |
2097 |
return err; |
2098 |
|
1896 |
data->in[nr][index] = in_to_reg(val, nr); |
2099 |
data->in[nr][index] = in_to_reg(val, nr); |
1897 |
nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], |
2100 |
data->write_value(data, data->REG_IN_MINMAX[index - 1][nr], |
1898 |
data->in[nr][index]); |
2101 |
data->in[nr][index]); |
1899 |
mutex_unlock(&data->update_lock); |
2102 |
data->unlock(data, dev); |
1900 |
return count; |
2103 |
return count; |
1901 |
} |
2104 |
} |
1902 |
|
2105 |
|
Lines 1919-1926
static int find_temp_source(struct nct6775_data *data, int index, int count)
Link Here
|
1919 |
for (nr = 0; nr < count; nr++) { |
2122 |
for (nr = 0; nr < count; nr++) { |
1920 |
int src; |
2123 |
int src; |
1921 |
|
2124 |
|
1922 |
src = nct6775_read_value(data, |
2125 |
src = data->read_value(data, |
1923 |
data->REG_TEMP_SOURCE[nr]) & 0x1f; |
2126 |
data->REG_TEMP_SOURCE[nr]) & 0x1f; |
1924 |
if (src == source) |
2127 |
if (src == source) |
1925 |
return nr; |
2128 |
return nr; |
1926 |
} |
2129 |
} |
Lines 1976-1989
store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
Link Here
|
1976 |
if (val > 1) |
2179 |
if (val > 1) |
1977 |
return -EINVAL; |
2180 |
return -EINVAL; |
1978 |
|
2181 |
|
1979 |
mutex_lock(&data->update_lock); |
2182 |
err = data->lock(data); |
|
|
2183 |
if (err) |
2184 |
return err; |
2185 |
|
1980 |
if (val) |
2186 |
if (val) |
1981 |
data->beeps |= (1ULL << nr); |
2187 |
data->beeps |= (1ULL << nr); |
1982 |
else |
2188 |
else |
1983 |
data->beeps &= ~(1ULL << nr); |
2189 |
data->beeps &= ~(1ULL << nr); |
1984 |
nct6775_write_value(data, data->REG_BEEP[regindex], |
2190 |
data->write_value(data, data->REG_BEEP[regindex], |
1985 |
(data->beeps >> (regindex << 3)) & 0xff); |
2191 |
(data->beeps >> (regindex << 3)) & 0xff); |
1986 |
mutex_unlock(&data->update_lock); |
2192 |
data->unlock(data, dev); |
1987 |
return count; |
2193 |
return count; |
1988 |
} |
2194 |
} |
1989 |
|
2195 |
|
Lines 2032-2045
store_temp_beep(struct device *dev, struct device_attribute *attr,
Link Here
|
2032 |
bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; |
2238 |
bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE]; |
2033 |
regindex = bit >> 3; |
2239 |
regindex = bit >> 3; |
2034 |
|
2240 |
|
2035 |
mutex_lock(&data->update_lock); |
2241 |
err = data->lock(data); |
|
|
2242 |
if (err) |
2243 |
return err; |
2244 |
|
2036 |
if (val) |
2245 |
if (val) |
2037 |
data->beeps |= (1ULL << bit); |
2246 |
data->beeps |= (1ULL << bit); |
2038 |
else |
2247 |
else |
2039 |
data->beeps &= ~(1ULL << bit); |
2248 |
data->beeps &= ~(1ULL << bit); |
2040 |
nct6775_write_value(data, data->REG_BEEP[regindex], |
2249 |
data->write_value(data, data->REG_BEEP[regindex], |
2041 |
(data->beeps >> (regindex << 3)) & 0xff); |
2250 |
(data->beeps >> (regindex << 3)) & 0xff); |
2042 |
mutex_unlock(&data->update_lock); |
2251 |
data->unlock(data, dev); |
2043 |
|
2252 |
|
2044 |
return count; |
2253 |
return count; |
2045 |
} |
2254 |
} |
Lines 2133-2139
store_fan_min(struct device *dev, struct device_attribute *attr,
Link Here
|
2133 |
if (err < 0) |
2342 |
if (err < 0) |
2134 |
return err; |
2343 |
return err; |
2135 |
|
2344 |
|
2136 |
mutex_lock(&data->update_lock); |
2345 |
err = data->lock(data); |
|
|
2346 |
if (err) |
2347 |
return err; |
2348 |
|
2137 |
if (!data->has_fan_div) { |
2349 |
if (!data->has_fan_div) { |
2138 |
/* NCT6776F or NCT6779D; we know this is a 13 bit register */ |
2350 |
/* NCT6776F or NCT6779D; we know this is a 13 bit register */ |
2139 |
if (!val) { |
2351 |
if (!val) { |
Lines 2205-2212
write_div:
Link Here
|
2205 |
} |
2417 |
} |
2206 |
|
2418 |
|
2207 |
write_min: |
2419 |
write_min: |
2208 |
nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]); |
2420 |
data->write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]); |
2209 |
mutex_unlock(&data->update_lock); |
2421 |
data->unlock(data, dev); |
2210 |
|
2422 |
|
2211 |
return count; |
2423 |
return count; |
2212 |
} |
2424 |
} |
Lines 2239-2251
store_fan_pulses(struct device *dev, struct device_attribute *attr,
Link Here
|
2239 |
if (val > 4) |
2451 |
if (val > 4) |
2240 |
return -EINVAL; |
2452 |
return -EINVAL; |
2241 |
|
2453 |
|
2242 |
mutex_lock(&data->update_lock); |
2454 |
err = data->lock(data); |
|
|
2455 |
if (err) |
2456 |
return err; |
2457 |
|
2243 |
data->fan_pulses[nr] = val & 3; |
2458 |
data->fan_pulses[nr] = val & 3; |
2244 |
reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]); |
2459 |
reg = data->read_value(data, data->REG_FAN_PULSES[nr]); |
2245 |
reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]); |
2460 |
reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]); |
2246 |
reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr]; |
2461 |
reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr]; |
2247 |
nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg); |
2462 |
data->write_value(data, data->REG_FAN_PULSES[nr], reg); |
2248 |
mutex_unlock(&data->update_lock); |
2463 |
data->unlock(data, dev); |
2249 |
|
2464 |
|
2250 |
return count; |
2465 |
return count; |
2251 |
} |
2466 |
} |
Lines 2343-2353
store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
Link Here
|
2343 |
if (err < 0) |
2558 |
if (err < 0) |
2344 |
return err; |
2559 |
return err; |
2345 |
|
2560 |
|
2346 |
mutex_lock(&data->update_lock); |
2561 |
err = data->lock(data); |
|
|
2562 |
if (err) |
2563 |
return err; |
2564 |
|
2347 |
data->temp[index][nr] = LM75_TEMP_TO_REG(val); |
2565 |
data->temp[index][nr] = LM75_TEMP_TO_REG(val); |
2348 |
nct6775_write_temp(data, data->reg_temp[index][nr], |
2566 |
nct6775_write_temp(data, data->reg_temp[index][nr], |
2349 |
data->temp[index][nr]); |
2567 |
data->temp[index][nr]); |
2350 |
mutex_unlock(&data->update_lock); |
2568 |
data->unlock(data, dev); |
2351 |
return count; |
2569 |
return count; |
2352 |
} |
2570 |
} |
2353 |
|
2571 |
|
Lines 2376-2385
store_temp_offset(struct device *dev, struct device_attribute *attr,
Link Here
|
2376 |
|
2594 |
|
2377 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); |
2595 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); |
2378 |
|
2596 |
|
2379 |
mutex_lock(&data->update_lock); |
2597 |
err = data->lock(data); |
|
|
2598 |
if (err) |
2599 |
return err; |
2600 |
|
2380 |
data->temp_offset[nr] = val; |
2601 |
data->temp_offset[nr] = val; |
2381 |
nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val); |
2602 |
data->write_value(data, data->REG_TEMP_OFFSET[nr], val); |
2382 |
mutex_unlock(&data->update_lock); |
2603 |
data->unlock(data, dev); |
2383 |
|
2604 |
|
2384 |
return count; |
2605 |
return count; |
2385 |
} |
2606 |
} |
Lines 2412-2424
store_temp_type(struct device *dev, struct device_attribute *attr,
Link Here
|
2412 |
if (val != 1 && val != 3 && val != 4) |
2633 |
if (val != 1 && val != 3 && val != 4) |
2413 |
return -EINVAL; |
2634 |
return -EINVAL; |
2414 |
|
2635 |
|
2415 |
mutex_lock(&data->update_lock); |
2636 |
err = data->lock(data); |
|
|
2637 |
if (err) |
2638 |
return err; |
2416 |
|
2639 |
|
2417 |
data->temp_type[nr] = val; |
2640 |
data->temp_type[nr] = val; |
2418 |
vbit = 0x02 << nr; |
2641 |
vbit = 0x02 << nr; |
2419 |
dbit = data->DIODE_MASK << nr; |
2642 |
dbit = data->DIODE_MASK << nr; |
2420 |
vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit; |
2643 |
vbat = data->read_value(data, data->REG_VBAT) & ~vbit; |
2421 |
diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit; |
2644 |
diode = data->read_value(data, data->REG_DIODE) & ~dbit; |
2422 |
switch (val) { |
2645 |
switch (val) { |
2423 |
case 1: /* CPU diode (diode, current mode) */ |
2646 |
case 1: /* CPU diode (diode, current mode) */ |
2424 |
vbat |= vbit; |
2647 |
vbat |= vbit; |
Lines 2430-2439
store_temp_type(struct device *dev, struct device_attribute *attr,
Link Here
|
2430 |
case 4: /* thermistor */ |
2653 |
case 4: /* thermistor */ |
2431 |
break; |
2654 |
break; |
2432 |
} |
2655 |
} |
2433 |
nct6775_write_value(data, data->REG_VBAT, vbat); |
2656 |
data->write_value(data, data->REG_VBAT, vbat); |
2434 |
nct6775_write_value(data, data->REG_DIODE, diode); |
2657 |
data->write_value(data, data->REG_DIODE, diode); |
2435 |
|
2658 |
|
2436 |
mutex_unlock(&data->update_lock); |
2659 |
data->unlock(data, dev); |
2437 |
return count; |
2660 |
return count; |
2438 |
} |
2661 |
} |
2439 |
|
2662 |
|
Lines 2553-2566
store_pwm_mode(struct device *dev, struct device_attribute *attr,
Link Here
|
2553 |
return count; |
2776 |
return count; |
2554 |
} |
2777 |
} |
2555 |
|
2778 |
|
2556 |
mutex_lock(&data->update_lock); |
2779 |
err = data->lock(data); |
|
|
2780 |
if (err) |
2781 |
return err; |
2782 |
|
2557 |
data->pwm_mode[nr] = val; |
2783 |
data->pwm_mode[nr] = val; |
2558 |
reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]); |
2784 |
reg = data->read_value(data, data->REG_PWM_MODE[nr]); |
2559 |
reg &= ~data->PWM_MODE_MASK[nr]; |
2785 |
reg &= ~data->PWM_MODE_MASK[nr]; |
2560 |
if (!val) |
2786 |
if (!val) |
2561 |
reg |= data->PWM_MODE_MASK[nr]; |
2787 |
reg |= data->PWM_MODE_MASK[nr]; |
2562 |
nct6775_write_value(data, data->REG_PWM_MODE[nr], reg); |
2788 |
data->write_value(data, data->REG_PWM_MODE[nr], reg); |
2563 |
mutex_unlock(&data->update_lock); |
2789 |
data->unlock(data, dev); |
2564 |
return count; |
2790 |
return count; |
2565 |
} |
2791 |
} |
2566 |
|
2792 |
|
Lines 2578-2584
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
Link Here
|
2578 |
* Otherwise, show the configured value. |
2804 |
* Otherwise, show the configured value. |
2579 |
*/ |
2805 |
*/ |
2580 |
if (index == 0 && data->pwm_enable[nr] > manual) |
2806 |
if (index == 0 && data->pwm_enable[nr] > manual) |
2581 |
pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]); |
2807 |
pwm = data->read_value(data, data->REG_PWM_READ[nr]); |
2582 |
else |
2808 |
else |
2583 |
pwm = data->pwm[index][nr]; |
2809 |
pwm = data->pwm[index][nr]; |
2584 |
|
2810 |
|
Lines 2605-2621
store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
Link Here
|
2605 |
return err; |
2831 |
return err; |
2606 |
val = clamp_val(val, minval[index], maxval[index]); |
2832 |
val = clamp_val(val, minval[index], maxval[index]); |
2607 |
|
2833 |
|
2608 |
mutex_lock(&data->update_lock); |
2834 |
err = data->lock(data); |
|
|
2835 |
if (err) |
2836 |
return err; |
2837 |
|
2609 |
data->pwm[index][nr] = val; |
2838 |
data->pwm[index][nr] = val; |
2610 |
nct6775_write_value(data, data->REG_PWM[index][nr], val); |
2839 |
data->write_value(data, data->REG_PWM[index][nr], val); |
2611 |
if (index == 2) { /* floor: disable if val == 0 */ |
2840 |
if (index == 2) { /* floor: disable if val == 0 */ |
2612 |
reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); |
2841 |
reg = data->read_value(data, data->REG_TEMP_SEL[nr]); |
2613 |
reg &= 0x7f; |
2842 |
reg &= 0x7f; |
2614 |
if (val) |
2843 |
if (val) |
2615 |
reg |= 0x80; |
2844 |
reg |= 0x80; |
2616 |
nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); |
2845 |
data->write_value(data, data->REG_TEMP_SEL[nr], reg); |
2617 |
} |
2846 |
} |
2618 |
mutex_unlock(&data->update_lock); |
2847 |
data->unlock(data, dev); |
2619 |
return count; |
2848 |
return count; |
2620 |
} |
2849 |
} |
2621 |
|
2850 |
|
Lines 2652-2680
static void pwm_update_registers(struct nct6775_data *data, int nr)
Link Here
|
2652 |
case manual: |
2881 |
case manual: |
2653 |
break; |
2882 |
break; |
2654 |
case speed_cruise: |
2883 |
case speed_cruise: |
2655 |
reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); |
2884 |
reg = data->read_value(data, data->REG_FAN_MODE[nr]); |
2656 |
reg = (reg & ~data->tolerance_mask) | |
2885 |
reg = (reg & ~data->tolerance_mask) | |
2657 |
(data->target_speed_tolerance[nr] & data->tolerance_mask); |
2886 |
(data->target_speed_tolerance[nr] & data->tolerance_mask); |
2658 |
nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); |
2887 |
data->write_value(data, data->REG_FAN_MODE[nr], reg); |
2659 |
nct6775_write_value(data, data->REG_TARGET[nr], |
2888 |
data->write_value(data, data->REG_TARGET[nr], |
2660 |
data->target_speed[nr] & 0xff); |
2889 |
data->target_speed[nr] & 0xff); |
2661 |
if (data->REG_TOLERANCE_H) { |
2890 |
if (data->REG_TOLERANCE_H) { |
2662 |
reg = (data->target_speed[nr] >> 8) & 0x0f; |
2891 |
reg = (data->target_speed[nr] >> 8) & 0x0f; |
2663 |
reg |= (data->target_speed_tolerance[nr] & 0x38) << 1; |
2892 |
reg |= (data->target_speed_tolerance[nr] & 0x38) << 1; |
2664 |
nct6775_write_value(data, |
2893 |
data->write_value(data, |
2665 |
data->REG_TOLERANCE_H[nr], |
2894 |
data->REG_TOLERANCE_H[nr], |
2666 |
reg); |
2895 |
reg); |
2667 |
} |
2896 |
} |
2668 |
break; |
2897 |
break; |
2669 |
case thermal_cruise: |
2898 |
case thermal_cruise: |
2670 |
nct6775_write_value(data, data->REG_TARGET[nr], |
2899 |
data->write_value(data, data->REG_TARGET[nr], |
2671 |
data->target_temp[nr]); |
2900 |
data->target_temp[nr]); |
2672 |
fallthrough; |
2901 |
fallthrough; |
2673 |
default: |
2902 |
default: |
2674 |
reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); |
2903 |
reg = data->read_value(data, data->REG_FAN_MODE[nr]); |
2675 |
reg = (reg & ~data->tolerance_mask) | |
2904 |
reg = (reg & ~data->tolerance_mask) | |
2676 |
data->temp_tolerance[0][nr]; |
2905 |
data->temp_tolerance[0][nr]; |
2677 |
nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); |
2906 |
data->write_value(data, data->REG_FAN_MODE[nr], reg); |
2678 |
break; |
2907 |
break; |
2679 |
} |
2908 |
} |
2680 |
} |
2909 |
} |
Lines 2715-2735
store_pwm_enable(struct device *dev, struct device_attribute *attr,
Link Here
|
2715 |
return -EINVAL; |
2944 |
return -EINVAL; |
2716 |
} |
2945 |
} |
2717 |
|
2946 |
|
2718 |
mutex_lock(&data->update_lock); |
2947 |
err = data->lock(data); |
|
|
2948 |
if (err) |
2949 |
return err; |
2950 |
|
2719 |
data->pwm_enable[nr] = val; |
2951 |
data->pwm_enable[nr] = val; |
2720 |
if (val == off) { |
2952 |
if (val == off) { |
2721 |
/* |
2953 |
/* |
2722 |
* turn off pwm control: select manual mode, set pwm to maximum |
2954 |
* turn off pwm control: select manual mode, set pwm to maximum |
2723 |
*/ |
2955 |
*/ |
2724 |
data->pwm[0][nr] = 255; |
2956 |
data->pwm[0][nr] = 255; |
2725 |
nct6775_write_value(data, data->REG_PWM[0][nr], 255); |
2957 |
data->write_value(data, data->REG_PWM[0][nr], 255); |
2726 |
} |
2958 |
} |
2727 |
pwm_update_registers(data, nr); |
2959 |
pwm_update_registers(data, nr); |
2728 |
reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]); |
2960 |
reg = data->read_value(data, data->REG_FAN_MODE[nr]); |
2729 |
reg &= 0x0f; |
2961 |
reg &= 0x0f; |
2730 |
reg |= pwm_enable_to_reg(val) << 4; |
2962 |
reg |= pwm_enable_to_reg(val) << 4; |
2731 |
nct6775_write_value(data, data->REG_FAN_MODE[nr], reg); |
2963 |
data->write_value(data, data->REG_FAN_MODE[nr], reg); |
2732 |
mutex_unlock(&data->update_lock); |
2964 |
data->unlock(data, dev); |
2733 |
return count; |
2965 |
return count; |
2734 |
} |
2966 |
} |
2735 |
|
2967 |
|
Lines 2778-2791
store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
Link Here
|
2778 |
if (!(data->have_temp & BIT(val - 1)) || !data->temp_src[val - 1]) |
3010 |
if (!(data->have_temp & BIT(val - 1)) || !data->temp_src[val - 1]) |
2779 |
return -EINVAL; |
3011 |
return -EINVAL; |
2780 |
|
3012 |
|
2781 |
mutex_lock(&data->update_lock); |
3013 |
err = data->lock(data); |
|
|
3014 |
if (err) |
3015 |
return err; |
3016 |
|
2782 |
src = data->temp_src[val - 1]; |
3017 |
src = data->temp_src[val - 1]; |
2783 |
data->pwm_temp_sel[nr] = src; |
3018 |
data->pwm_temp_sel[nr] = src; |
2784 |
reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]); |
3019 |
reg = data->read_value(data, data->REG_TEMP_SEL[nr]); |
2785 |
reg &= 0xe0; |
3020 |
reg &= 0xe0; |
2786 |
reg |= src; |
3021 |
reg |= src; |
2787 |
nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg); |
3022 |
data->write_value(data, data->REG_TEMP_SEL[nr], reg); |
2788 |
mutex_unlock(&data->update_lock); |
3023 |
data->unlock(data, dev); |
2789 |
|
3024 |
|
2790 |
return count; |
3025 |
return count; |
2791 |
} |
3026 |
} |
Lines 2822-2842
store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
Link Here
|
2822 |
!data->temp_src[val - 1])) |
3057 |
!data->temp_src[val - 1])) |
2823 |
return -EINVAL; |
3058 |
return -EINVAL; |
2824 |
|
3059 |
|
2825 |
mutex_lock(&data->update_lock); |
3060 |
err = data->lock(data); |
|
|
3061 |
if (err) |
3062 |
return err; |
3063 |
|
2826 |
if (val) { |
3064 |
if (val) { |
2827 |
src = data->temp_src[val - 1]; |
3065 |
src = data->temp_src[val - 1]; |
2828 |
data->pwm_weight_temp_sel[nr] = src; |
3066 |
data->pwm_weight_temp_sel[nr] = src; |
2829 |
reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); |
3067 |
reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); |
2830 |
reg &= 0xe0; |
3068 |
reg &= 0xe0; |
2831 |
reg |= (src | 0x80); |
3069 |
reg |= (src | 0x80); |
2832 |
nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); |
3070 |
data->write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); |
2833 |
} else { |
3071 |
} else { |
2834 |
data->pwm_weight_temp_sel[nr] = 0; |
3072 |
data->pwm_weight_temp_sel[nr] = 0; |
2835 |
reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); |
3073 |
reg = data->read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]); |
2836 |
reg &= 0x7f; |
3074 |
reg &= 0x7f; |
2837 |
nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); |
3075 |
data->write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg); |
2838 |
} |
3076 |
} |
2839 |
mutex_unlock(&data->update_lock); |
3077 |
data->unlock(data, dev); |
2840 |
|
3078 |
|
2841 |
return count; |
3079 |
return count; |
2842 |
} |
3080 |
} |
Lines 2867-2876
store_target_temp(struct device *dev, struct device_attribute *attr,
Link Here
|
2867 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, |
3105 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, |
2868 |
data->target_temp_mask); |
3106 |
data->target_temp_mask); |
2869 |
|
3107 |
|
2870 |
mutex_lock(&data->update_lock); |
3108 |
err = data->lock(data); |
|
|
3109 |
if (err) |
3110 |
return err; |
3111 |
|
2871 |
data->target_temp[nr] = val; |
3112 |
data->target_temp[nr] = val; |
2872 |
pwm_update_registers(data, nr); |
3113 |
pwm_update_registers(data, nr); |
2873 |
mutex_unlock(&data->update_lock); |
3114 |
data->unlock(data, dev); |
2874 |
return count; |
3115 |
return count; |
2875 |
} |
3116 |
} |
2876 |
|
3117 |
|
Lines 2904-2913
store_target_speed(struct device *dev, struct device_attribute *attr,
Link Here
|
2904 |
val = clamp_val(val, 0, 1350000U); |
3145 |
val = clamp_val(val, 0, 1350000U); |
2905 |
speed = fan_to_reg(val, data->fan_div[nr]); |
3146 |
speed = fan_to_reg(val, data->fan_div[nr]); |
2906 |
|
3147 |
|
2907 |
mutex_lock(&data->update_lock); |
3148 |
err = data->lock(data); |
|
|
3149 |
if (err) |
3150 |
return err; |
3151 |
|
2908 |
data->target_speed[nr] = speed; |
3152 |
data->target_speed[nr] = speed; |
2909 |
pwm_update_registers(data, nr); |
3153 |
pwm_update_registers(data, nr); |
2910 |
mutex_unlock(&data->update_lock); |
3154 |
data->unlock(data, dev); |
2911 |
return count; |
3155 |
return count; |
2912 |
} |
3156 |
} |
2913 |
|
3157 |
|
Lines 2941-2955
store_temp_tolerance(struct device *dev, struct device_attribute *attr,
Link Here
|
2941 |
/* Limit tolerance as needed */ |
3185 |
/* Limit tolerance as needed */ |
2942 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask); |
3186 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask); |
2943 |
|
3187 |
|
2944 |
mutex_lock(&data->update_lock); |
3188 |
err = data->lock(data); |
|
|
3189 |
if (err) |
3190 |
return err; |
3191 |
|
2945 |
data->temp_tolerance[index][nr] = val; |
3192 |
data->temp_tolerance[index][nr] = val; |
2946 |
if (index) |
3193 |
if (index) |
2947 |
pwm_update_registers(data, nr); |
3194 |
pwm_update_registers(data, nr); |
2948 |
else |
3195 |
else |
2949 |
nct6775_write_value(data, |
3196 |
data->write_value(data, |
2950 |
data->REG_CRITICAL_TEMP_TOLERANCE[nr], |
3197 |
data->REG_CRITICAL_TEMP_TOLERANCE[nr], |
2951 |
val); |
3198 |
val); |
2952 |
mutex_unlock(&data->update_lock); |
3199 |
data->unlock(data, dev); |
2953 |
return count; |
3200 |
return count; |
2954 |
} |
3201 |
} |
2955 |
|
3202 |
|
Lines 3018-3027
store_speed_tolerance(struct device *dev, struct device_attribute *attr,
Link Here
|
3018 |
/* Limit tolerance as needed */ |
3265 |
/* Limit tolerance as needed */ |
3019 |
val = clamp_val(val, 0, data->speed_tolerance_limit); |
3266 |
val = clamp_val(val, 0, data->speed_tolerance_limit); |
3020 |
|
3267 |
|
3021 |
mutex_lock(&data->update_lock); |
3268 |
err = data->lock(data); |
|
|
3269 |
if (err) |
3270 |
return err; |
3271 |
|
3022 |
data->target_speed_tolerance[nr] = val; |
3272 |
data->target_speed_tolerance[nr] = val; |
3023 |
pwm_update_registers(data, nr); |
3273 |
pwm_update_registers(data, nr); |
3024 |
mutex_unlock(&data->update_lock); |
3274 |
data->unlock(data, dev); |
3025 |
return count; |
3275 |
return count; |
3026 |
} |
3276 |
} |
3027 |
|
3277 |
|
Lines 3069-3078
store_weight_temp(struct device *dev, struct device_attribute *attr,
Link Here
|
3069 |
|
3319 |
|
3070 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); |
3320 |
val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); |
3071 |
|
3321 |
|
3072 |
mutex_lock(&data->update_lock); |
3322 |
err = data->lock(data); |
|
|
3323 |
if (err) |
3324 |
return err; |
3325 |
|
3073 |
data->weight_temp[index][nr] = val; |
3326 |
data->weight_temp[index][nr] = val; |
3074 |
nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val); |
3327 |
data->write_value(data, data->REG_WEIGHT_TEMP[index][nr], val); |
3075 |
mutex_unlock(&data->update_lock); |
3328 |
data->unlock(data, dev); |
3076 |
return count; |
3329 |
return count; |
3077 |
} |
3330 |
} |
3078 |
|
3331 |
|
Lines 3118-3127
store_fan_time(struct device *dev, struct device_attribute *attr,
Link Here
|
3118 |
return err; |
3371 |
return err; |
3119 |
|
3372 |
|
3120 |
val = step_time_to_reg(val, data->pwm_mode[nr]); |
3373 |
val = step_time_to_reg(val, data->pwm_mode[nr]); |
3121 |
mutex_lock(&data->update_lock); |
3374 |
err = data->lock(data); |
|
|
3375 |
if (err) |
3376 |
return err; |
3377 |
|
3122 |
data->fan_time[index][nr] = val; |
3378 |
data->fan_time[index][nr] = val; |
3123 |
nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val); |
3379 |
data->write_value(data, data->REG_FAN_TIME[index][nr], val); |
3124 |
mutex_unlock(&data->update_lock); |
3380 |
data->unlock(data, dev); |
3125 |
return count; |
3381 |
return count; |
3126 |
} |
3382 |
} |
3127 |
|
3383 |
|
Lines 3159-3182
store_auto_pwm(struct device *dev, struct device_attribute *attr,
Link Here
|
3159 |
val = 0xff; |
3415 |
val = 0xff; |
3160 |
} |
3416 |
} |
3161 |
|
3417 |
|
3162 |
mutex_lock(&data->update_lock); |
3418 |
err = data->lock(data); |
|
|
3419 |
if (err) |
3420 |
return err; |
3421 |
|
3163 |
data->auto_pwm[nr][point] = val; |
3422 |
data->auto_pwm[nr][point] = val; |
3164 |
if (point < data->auto_pwm_num) { |
3423 |
if (point < data->auto_pwm_num) { |
3165 |
nct6775_write_value(data, |
3424 |
data->write_value(data, |
3166 |
NCT6775_AUTO_PWM(data, nr, point), |
3425 |
NCT6775_AUTO_PWM(data, nr, point), |
3167 |
data->auto_pwm[nr][point]); |
3426 |
data->auto_pwm[nr][point]); |
3168 |
} else { |
3427 |
} else { |
3169 |
switch (data->kind) { |
3428 |
switch (data->kind) { |
3170 |
case nct6775: |
3429 |
case nct6775: |
3171 |
/* disable if needed (pwm == 0) */ |
3430 |
/* disable if needed (pwm == 0) */ |
3172 |
reg = nct6775_read_value(data, |
3431 |
reg = data->read_value(data, |
3173 |
NCT6775_REG_CRITICAL_ENAB[nr]); |
3432 |
NCT6775_REG_CRITICAL_ENAB[nr]); |
3174 |
if (val) |
3433 |
if (val) |
3175 |
reg |= 0x02; |
3434 |
reg |= 0x02; |
3176 |
else |
3435 |
else |
3177 |
reg &= ~0x02; |
3436 |
reg &= ~0x02; |
3178 |
nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr], |
3437 |
data->write_value(data, NCT6775_REG_CRITICAL_ENAB[nr], |
3179 |
reg); |
3438 |
reg); |
3180 |
break; |
3439 |
break; |
3181 |
case nct6776: |
3440 |
case nct6776: |
3182 |
break; /* always enabled, nothing to do */ |
3441 |
break; /* always enabled, nothing to do */ |
Lines 3190-3210
store_auto_pwm(struct device *dev, struct device_attribute *attr,
Link Here
|
3190 |
case nct6796: |
3449 |
case nct6796: |
3191 |
case nct6797: |
3450 |
case nct6797: |
3192 |
case nct6798: |
3451 |
case nct6798: |
3193 |
nct6775_write_value(data, data->REG_CRITICAL_PWM[nr], |
3452 |
data->write_value(data, data->REG_CRITICAL_PWM[nr], |
3194 |
val); |
3453 |
val); |
3195 |
reg = nct6775_read_value(data, |
3454 |
reg = data->read_value(data, |
3196 |
data->REG_CRITICAL_PWM_ENABLE[nr]); |
3455 |
data->REG_CRITICAL_PWM_ENABLE[nr]); |
3197 |
if (val == 255) |
3456 |
if (val == 255) |
3198 |
reg &= ~data->CRITICAL_PWM_ENABLE_MASK; |
3457 |
reg &= ~data->CRITICAL_PWM_ENABLE_MASK; |
3199 |
else |
3458 |
else |
3200 |
reg |= data->CRITICAL_PWM_ENABLE_MASK; |
3459 |
reg |= data->CRITICAL_PWM_ENABLE_MASK; |
3201 |
nct6775_write_value(data, |
3460 |
data->write_value(data, |
3202 |
data->REG_CRITICAL_PWM_ENABLE[nr], |
3461 |
data->REG_CRITICAL_PWM_ENABLE[nr], |
3203 |
reg); |
3462 |
reg); |
3204 |
break; |
3463 |
break; |
3205 |
} |
3464 |
} |
3206 |
} |
3465 |
} |
3207 |
mutex_unlock(&data->update_lock); |
3466 |
data->unlock(data, dev); |
3208 |
return count; |
3467 |
return count; |
3209 |
} |
3468 |
} |
3210 |
|
3469 |
|
Lines 3240-3256
store_auto_temp(struct device *dev, struct device_attribute *attr,
Link Here
|
3240 |
if (val > 255000) |
3499 |
if (val > 255000) |
3241 |
return -EINVAL; |
3500 |
return -EINVAL; |
3242 |
|
3501 |
|
3243 |
mutex_lock(&data->update_lock); |
3502 |
err = data->lock(data); |
|
|
3503 |
if (err) |
3504 |
return err; |
3505 |
|
3244 |
data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000); |
3506 |
data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000); |
3245 |
if (point < data->auto_pwm_num) { |
3507 |
if (point < data->auto_pwm_num) { |
3246 |
nct6775_write_value(data, |
3508 |
data->write_value(data, |
3247 |
NCT6775_AUTO_TEMP(data, nr, point), |
3509 |
NCT6775_AUTO_TEMP(data, nr, point), |
3248 |
data->auto_temp[nr][point]); |
3510 |
data->auto_temp[nr][point]); |
3249 |
} else { |
3511 |
} else { |
3250 |
nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr], |
3512 |
data->write_value(data, data->REG_CRITICAL_TEMP[nr], |
3251 |
data->auto_temp[nr][point]); |
3513 |
data->auto_temp[nr][point]); |
3252 |
} |
3514 |
} |
3253 |
mutex_unlock(&data->update_lock); |
3515 |
data->unlock(data, dev); |
3254 |
return count; |
3516 |
return count; |
3255 |
} |
3517 |
} |
3256 |
|
3518 |
|
Lines 3410-3415
clear_caseopen(struct device *dev, struct device_attribute *attr,
Link Here
|
3410 |
const char *buf, size_t count) |
3672 |
const char *buf, size_t count) |
3411 |
{ |
3673 |
{ |
3412 |
struct nct6775_data *data = dev_get_drvdata(dev); |
3674 |
struct nct6775_data *data = dev_get_drvdata(dev); |
|
|
3675 |
struct nct6775_sio_data *sio_data = dev_get_platdata(dev); |
3413 |
int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE; |
3676 |
int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE; |
3414 |
unsigned long val; |
3677 |
unsigned long val; |
3415 |
u8 reg; |
3678 |
u8 reg; |
Lines 3418-3447
clear_caseopen(struct device *dev, struct device_attribute *attr,
Link Here
|
3418 |
if (kstrtoul(buf, 10, &val) || val != 0) |
3681 |
if (kstrtoul(buf, 10, &val) || val != 0) |
3419 |
return -EINVAL; |
3682 |
return -EINVAL; |
3420 |
|
3683 |
|
3421 |
mutex_lock(&data->update_lock); |
3684 |
ret = data->lock(data); |
|
|
3685 |
if (ret) |
3686 |
return ret; |
3422 |
|
3687 |
|
3423 |
/* |
3688 |
/* |
3424 |
* Use CR registers to clear caseopen status. |
3689 |
* Use CR registers to clear caseopen status. |
3425 |
* The CR registers are the same for all chips, and not all chips |
3690 |
* The CR registers are the same for all chips, and not all chips |
3426 |
* support clearing the caseopen status through "regular" registers. |
3691 |
* support clearing the caseopen status through "regular" registers. |
3427 |
*/ |
3692 |
*/ |
3428 |
ret = superio_enter(data->sioreg); |
3693 |
ret = sio_data->sio_enter(sio_data); |
3429 |
if (ret) { |
3694 |
if (ret) { |
3430 |
count = ret; |
3695 |
count = ret; |
3431 |
goto error; |
3696 |
goto error; |
3432 |
} |
3697 |
} |
3433 |
|
3698 |
|
3434 |
superio_select(data->sioreg, NCT6775_LD_ACPI); |
3699 |
sio_data->sio_select(sio_data, NCT6775_LD_ACPI); |
3435 |
reg = superio_inb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]); |
3700 |
reg = sio_data->sio_inb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr]); |
3436 |
reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr]; |
3701 |
reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr]; |
3437 |
superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); |
3702 |
sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); |
3438 |
reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr]; |
3703 |
reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr]; |
3439 |
superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); |
3704 |
sio_data->sio_outb(sio_data, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg); |
3440 |
superio_exit(data->sioreg); |
3705 |
sio_data->sio_exit(sio_data); |
3441 |
|
3706 |
|
3442 |
data->valid = false; /* Force cache refresh */ |
3707 |
data->valid = false; /* Force cache refresh */ |
3443 |
error: |
3708 |
error: |
3444 |
mutex_unlock(&data->update_lock); |
3709 |
data->unlock(data, dev); |
3445 |
return count; |
3710 |
return count; |
3446 |
} |
3711 |
} |
3447 |
|
3712 |
|
Lines 3506-3514
static inline void nct6775_init_device(struct nct6775_data *data)
Link Here
|
3506 |
|
3771 |
|
3507 |
/* Start monitoring if needed */ |
3772 |
/* Start monitoring if needed */ |
3508 |
if (data->REG_CONFIG) { |
3773 |
if (data->REG_CONFIG) { |
3509 |
tmp = nct6775_read_value(data, data->REG_CONFIG); |
3774 |
tmp = data->read_value(data, data->REG_CONFIG); |
3510 |
if (!(tmp & 0x01)) |
3775 |
if (!(tmp & 0x01)) |
3511 |
nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01); |
3776 |
data->write_value(data, data->REG_CONFIG, tmp | 0x01); |
3512 |
} |
3777 |
} |
3513 |
|
3778 |
|
3514 |
/* Enable temperature sensors if needed */ |
3779 |
/* Enable temperature sensors if needed */ |
Lines 3517-3534
static inline void nct6775_init_device(struct nct6775_data *data)
Link Here
|
3517 |
continue; |
3782 |
continue; |
3518 |
if (!data->reg_temp_config[i]) |
3783 |
if (!data->reg_temp_config[i]) |
3519 |
continue; |
3784 |
continue; |
3520 |
tmp = nct6775_read_value(data, data->reg_temp_config[i]); |
3785 |
tmp = data->read_value(data, data->reg_temp_config[i]); |
3521 |
if (tmp & 0x01) |
3786 |
if (tmp & 0x01) |
3522 |
nct6775_write_value(data, data->reg_temp_config[i], |
3787 |
data->write_value(data, data->reg_temp_config[i], |
3523 |
tmp & 0xfe); |
3788 |
tmp & 0xfe); |
3524 |
} |
3789 |
} |
3525 |
|
3790 |
|
3526 |
/* Enable VBAT monitoring if needed */ |
3791 |
/* Enable VBAT monitoring if needed */ |
3527 |
tmp = nct6775_read_value(data, data->REG_VBAT); |
3792 |
tmp = data->read_value(data, data->REG_VBAT); |
3528 |
if (!(tmp & 0x01)) |
3793 |
if (!(tmp & 0x01)) |
3529 |
nct6775_write_value(data, data->REG_VBAT, tmp | 0x01); |
3794 |
data->write_value(data, data->REG_VBAT, tmp | 0x01); |
3530 |
|
3795 |
|
3531 |
diode = nct6775_read_value(data, data->REG_DIODE); |
3796 |
diode = data->read_value(data, data->REG_DIODE); |
3532 |
|
3797 |
|
3533 |
for (i = 0; i < data->temp_fixed_num; i++) { |
3798 |
for (i = 0; i < data->temp_fixed_num; i++) { |
3534 |
if (!(data->have_temp_fixed & BIT(i))) |
3799 |
if (!(data->have_temp_fixed & BIT(i))) |
Lines 3542-3570
static inline void nct6775_init_device(struct nct6775_data *data)
Link Here
|
3542 |
} |
3807 |
} |
3543 |
|
3808 |
|
3544 |
static void |
3809 |
static void |
3545 |
nct6775_check_fan_inputs(struct nct6775_data *data) |
3810 |
nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio_data) |
3546 |
{ |
3811 |
{ |
3547 |
bool fan3pin = false, fan4pin = false, fan4min = false; |
3812 |
bool fan3pin = false, fan4pin = false, fan4min = false; |
3548 |
bool fan5pin = false, fan6pin = false, fan7pin = false; |
3813 |
bool fan5pin = false, fan6pin = false, fan7pin = false; |
3549 |
bool pwm3pin = false, pwm4pin = false, pwm5pin = false; |
3814 |
bool pwm3pin = false, pwm4pin = false, pwm5pin = false; |
3550 |
bool pwm6pin = false, pwm7pin = false; |
3815 |
bool pwm6pin = false, pwm7pin = false; |
3551 |
int sioreg = data->sioreg; |
|
|
3552 |
|
3816 |
|
3553 |
/* Store SIO_REG_ENABLE for use during resume */ |
3817 |
/* Store SIO_REG_ENABLE for use during resume */ |
3554 |
superio_select(sioreg, NCT6775_LD_HWM); |
3818 |
sio_data->sio_select(sio_data, NCT6775_LD_HWM); |
3555 |
data->sio_reg_enable = superio_inb(sioreg, SIO_REG_ENABLE); |
3819 |
data->sio_reg_enable = sio_data->sio_inb(sio_data, SIO_REG_ENABLE); |
3556 |
|
3820 |
|
3557 |
/* fan4 and fan5 share some pins with the GPIO and serial flash */ |
3821 |
/* fan4 and fan5 share some pins with the GPIO and serial flash */ |
3558 |
if (data->kind == nct6775) { |
3822 |
if (data->kind == nct6775) { |
3559 |
int cr2c = superio_inb(sioreg, 0x2c); |
3823 |
int cr2c = sio_data->sio_inb(sio_data, 0x2c); |
3560 |
|
3824 |
|
3561 |
fan3pin = cr2c & BIT(6); |
3825 |
fan3pin = cr2c & BIT(6); |
3562 |
pwm3pin = cr2c & BIT(7); |
3826 |
pwm3pin = cr2c & BIT(7); |
3563 |
|
3827 |
|
3564 |
/* On NCT6775, fan4 shares pins with the fdc interface */ |
3828 |
/* On NCT6775, fan4 shares pins with the fdc interface */ |
3565 |
fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80); |
3829 |
fan4pin = !(sio_data->sio_inb(sio_data, 0x2A) & 0x80); |
3566 |
} else if (data->kind == nct6776) { |
3830 |
} else if (data->kind == nct6776) { |
3567 |
bool gpok = superio_inb(sioreg, 0x27) & 0x80; |
3831 |
bool gpok = sio_data->sio_inb(sio_data, 0x27) & 0x80; |
3568 |
const char *board_vendor, *board_name; |
3832 |
const char *board_vendor, *board_name; |
3569 |
|
3833 |
|
3570 |
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); |
3834 |
board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); |
Lines 3580-3586
nct6775_check_fan_inputs(struct nct6775_data *data)
Link Here
|
3580 |
if (!strcmp(board_name, "Z77 Pro4-M")) { |
3844 |
if (!strcmp(board_name, "Z77 Pro4-M")) { |
3581 |
if ((data->sio_reg_enable & 0xe0) != 0xe0) { |
3845 |
if ((data->sio_reg_enable & 0xe0) != 0xe0) { |
3582 |
data->sio_reg_enable |= 0xe0; |
3846 |
data->sio_reg_enable |= 0xe0; |
3583 |
superio_outb(sioreg, SIO_REG_ENABLE, |
3847 |
sio_data->sio_outb(sio_data, SIO_REG_ENABLE, |
3584 |
data->sio_reg_enable); |
3848 |
data->sio_reg_enable); |
3585 |
} |
3849 |
} |
3586 |
} |
3850 |
} |
Lines 3589-3620
nct6775_check_fan_inputs(struct nct6775_data *data)
Link Here
|
3589 |
if (data->sio_reg_enable & 0x80) |
3853 |
if (data->sio_reg_enable & 0x80) |
3590 |
fan3pin = gpok; |
3854 |
fan3pin = gpok; |
3591 |
else |
3855 |
else |
3592 |
fan3pin = !(superio_inb(sioreg, 0x24) & 0x40); |
3856 |
fan3pin = !(sio_data->sio_inb(sio_data, 0x24) & 0x40); |
3593 |
|
3857 |
|
3594 |
if (data->sio_reg_enable & 0x40) |
3858 |
if (data->sio_reg_enable & 0x40) |
3595 |
fan4pin = gpok; |
3859 |
fan4pin = gpok; |
3596 |
else |
3860 |
else |
3597 |
fan4pin = superio_inb(sioreg, 0x1C) & 0x01; |
3861 |
fan4pin = sio_data->sio_inb(sio_data, 0x1C) & 0x01; |
3598 |
|
3862 |
|
3599 |
if (data->sio_reg_enable & 0x20) |
3863 |
if (data->sio_reg_enable & 0x20) |
3600 |
fan5pin = gpok; |
3864 |
fan5pin = gpok; |
3601 |
else |
3865 |
else |
3602 |
fan5pin = superio_inb(sioreg, 0x1C) & 0x02; |
3866 |
fan5pin = sio_data->sio_inb(sio_data, 0x1C) & 0x02; |
3603 |
|
3867 |
|
3604 |
fan4min = fan4pin; |
3868 |
fan4min = fan4pin; |
3605 |
pwm3pin = fan3pin; |
3869 |
pwm3pin = fan3pin; |
3606 |
} else if (data->kind == nct6106) { |
3870 |
} else if (data->kind == nct6106) { |
3607 |
int cr24 = superio_inb(sioreg, 0x24); |
3871 |
int cr24 = sio_data->sio_inb(sio_data, 0x24); |
3608 |
|
3872 |
|
3609 |
fan3pin = !(cr24 & 0x80); |
3873 |
fan3pin = !(cr24 & 0x80); |
3610 |
pwm3pin = cr24 & 0x08; |
3874 |
pwm3pin = cr24 & 0x08; |
3611 |
} else if (data->kind == nct6116) { |
3875 |
} else if (data->kind == nct6116) { |
3612 |
int cr1a = superio_inb(sioreg, 0x1a); |
3876 |
int cr1a = sio_data->sio_inb(sio_data, 0x1a); |
3613 |
int cr1b = superio_inb(sioreg, 0x1b); |
3877 |
int cr1b = sio_data->sio_inb(sio_data, 0x1b); |
3614 |
int cr24 = superio_inb(sioreg, 0x24); |
3878 |
int cr24 = sio_data->sio_inb(sio_data, 0x24); |
3615 |
int cr2a = superio_inb(sioreg, 0x2a); |
3879 |
int cr2a = sio_data->sio_inb(sio_data, 0x2a); |
3616 |
int cr2b = superio_inb(sioreg, 0x2b); |
3880 |
int cr2b = sio_data->sio_inb(sio_data, 0x2b); |
3617 |
int cr2f = superio_inb(sioreg, 0x2f); |
3881 |
int cr2f = sio_data->sio_inb(sio_data, 0x2f); |
3618 |
|
3882 |
|
3619 |
fan3pin = !(cr2b & 0x10); |
3883 |
fan3pin = !(cr2b & 0x10); |
3620 |
fan4pin = (cr2b & 0x80) || // pin 1(2) |
3884 |
fan4pin = (cr2b & 0x80) || // pin 1(2) |
Lines 3630-3653
nct6775_check_fan_inputs(struct nct6775_data *data)
Link Here
|
3630 |
* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D, |
3894 |
* NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D, |
3631 |
* NCT6797D, NCT6798D |
3895 |
* NCT6797D, NCT6798D |
3632 |
*/ |
3896 |
*/ |
3633 |
int cr1a = superio_inb(sioreg, 0x1a); |
3897 |
int cr1a = sio_data->sio_inb(sio_data, 0x1a); |
3634 |
int cr1b = superio_inb(sioreg, 0x1b); |
3898 |
int cr1b = sio_data->sio_inb(sio_data, 0x1b); |
3635 |
int cr1c = superio_inb(sioreg, 0x1c); |
3899 |
int cr1c = sio_data->sio_inb(sio_data, 0x1c); |
3636 |
int cr1d = superio_inb(sioreg, 0x1d); |
3900 |
int cr1d = sio_data->sio_inb(sio_data, 0x1d); |
3637 |
int cr2a = superio_inb(sioreg, 0x2a); |
3901 |
int cr2a = sio_data->sio_inb(sio_data, 0x2a); |
3638 |
int cr2b = superio_inb(sioreg, 0x2b); |
3902 |
int cr2b = sio_data->sio_inb(sio_data, 0x2b); |
3639 |
int cr2d = superio_inb(sioreg, 0x2d); |
3903 |
int cr2d = sio_data->sio_inb(sio_data, 0x2d); |
3640 |
int cr2f = superio_inb(sioreg, 0x2f); |
3904 |
int cr2f = sio_data->sio_inb(sio_data, 0x2f); |
3641 |
bool dsw_en = cr2f & BIT(3); |
3905 |
bool dsw_en = cr2f & BIT(3); |
3642 |
bool ddr4_en = cr2f & BIT(4); |
3906 |
bool ddr4_en = cr2f & BIT(4); |
3643 |
int cre0; |
3907 |
int cre0; |
3644 |
int creb; |
3908 |
int creb; |
3645 |
int cred; |
3909 |
int cred; |
3646 |
|
3910 |
|
3647 |
superio_select(sioreg, NCT6775_LD_12); |
3911 |
sio_data->sio_select(sio_data, NCT6775_LD_12); |
3648 |
cre0 = superio_inb(sioreg, 0xe0); |
3912 |
cre0 = sio_data->sio_inb(sio_data, 0xe0); |
3649 |
creb = superio_inb(sioreg, 0xeb); |
3913 |
creb = sio_data->sio_inb(sio_data, 0xeb); |
3650 |
cred = superio_inb(sioreg, 0xed); |
3914 |
cred = sio_data->sio_inb(sio_data, 0xed); |
3651 |
|
3915 |
|
3652 |
fan3pin = !(cr1c & BIT(5)); |
3916 |
fan3pin = !(cr1c & BIT(5)); |
3653 |
fan4pin = !(cr1c & BIT(6)); |
3917 |
fan4pin = !(cr1c & BIT(6)); |
Lines 3774-3780
static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
Link Here
|
3774 |
|
4038 |
|
3775 |
if (!regp[i]) |
4039 |
if (!regp[i]) |
3776 |
continue; |
4040 |
continue; |
3777 |
src = nct6775_read_value(data, regp[i]); |
4041 |
src = data->read_value(data, regp[i]); |
3778 |
src &= 0x1f; |
4042 |
src &= 0x1f; |
3779 |
if (!src || (*mask & BIT(src))) |
4043 |
if (!src || (*mask & BIT(src))) |
3780 |
continue; |
4044 |
continue; |
Lines 3782-3793
static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
Link Here
|
3782 |
continue; |
4046 |
continue; |
3783 |
|
4047 |
|
3784 |
index = __ffs(*available); |
4048 |
index = __ffs(*available); |
3785 |
nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src); |
4049 |
data->write_value(data, data->REG_TEMP_SOURCE[index], src); |
3786 |
*available &= ~BIT(index); |
4050 |
*available &= ~BIT(index); |
3787 |
*mask |= BIT(src); |
4051 |
*mask |= BIT(src); |
3788 |
} |
4052 |
} |
3789 |
} |
4053 |
} |
3790 |
|
4054 |
|
|
|
4055 |
/* Nuvoton SMBus address offsets */ |
4056 |
#define SMBHSTDAT 0 |
4057 |
#define SMBBLKSZ 1 |
4058 |
#define SMBHSTCMD 2 |
4059 |
//Index field is the Command field on other controllers |
4060 |
#define SMBHSTIDX 3 |
4061 |
#define SMBHSTCTL 4 |
4062 |
#define SMBHSTADD 5 |
4063 |
#define SMBHSTERR 9 |
4064 |
#define SMBHSTSTS 0xE |
4065 |
|
4066 |
/* Command register */ |
4067 |
#define NCT6793D_READ_BYTE 0 |
4068 |
#define NCT6793D_READ_WORD 1 |
4069 |
#define NCT6793D_WRITE_BYTE 8 |
4070 |
#define NCT6793D_WRITE_WORD 9 |
4071 |
#define NCT6793D_WRITE_BLOCK 10 |
4072 |
|
4073 |
/* Control register */ |
4074 |
#define NCT6793D_MANUAL_START 128 |
4075 |
#define NCT6793D_SOFT_RESET 64 |
4076 |
|
4077 |
/* Error register */ |
4078 |
#define NCT6793D_NO_ACK 32 |
4079 |
|
4080 |
/* Status register */ |
4081 |
#define NCT6793D_FIFO_EMPTY 1 |
4082 |
#define NCT6793D_MANUAL_ACTIVE 4 |
4083 |
|
4084 |
/* Other settings */ |
4085 |
#define MAX_RETRIES 400 |
4086 |
|
4087 |
/* Return negative errno on error. */ |
4088 |
static s32 nct6775_i2c_access(struct i2c_adapter *adap, u16 addr, |
4089 |
unsigned short flags, char read_write, |
4090 |
u8 command, int size, union i2c_smbus_data *data) |
4091 |
{ |
4092 |
struct nct6775_data *adapdata = i2c_get_adapdata(adap); |
4093 |
union i2c_smbus_data tmp_data; |
4094 |
int timeout = 0, ret; |
4095 |
int i, len, cnt; |
4096 |
|
4097 |
tmp_data.word = 0; |
4098 |
cnt = 0; |
4099 |
len = 0; |
4100 |
|
4101 |
ret = adapdata->lock(adapdata); |
4102 |
if (ret) |
4103 |
return ret; |
4104 |
|
4105 |
outb_p(NCT6793D_SOFT_RESET, adapdata->addr + SMBHSTCTL); |
4106 |
|
4107 |
switch (size) { |
4108 |
case I2C_SMBUS_QUICK: |
4109 |
outb_p((addr << 1) | read_write, |
4110 |
adapdata->addr + SMBHSTADD); |
4111 |
break; |
4112 |
case I2C_SMBUS_BYTE_DATA: |
4113 |
tmp_data.byte = data->byte; |
4114 |
outb_p((addr << 1) | read_write, |
4115 |
adapdata->addr + SMBHSTADD); |
4116 |
outb_p(command, adapdata->addr + SMBHSTIDX); |
4117 |
if (read_write == I2C_SMBUS_WRITE) { |
4118 |
outb_p(tmp_data.byte, adapdata->addr + SMBHSTDAT); |
4119 |
outb_p(NCT6793D_WRITE_BYTE, adapdata->addr + SMBHSTCMD); |
4120 |
} else { |
4121 |
outb_p(NCT6793D_READ_BYTE, adapdata->addr + SMBHSTCMD); |
4122 |
} |
4123 |
break; |
4124 |
case I2C_SMBUS_BYTE: |
4125 |
outb_p((addr << 1) | read_write, |
4126 |
adapdata->addr + SMBHSTADD); |
4127 |
outb_p(command, adapdata->addr + SMBHSTIDX); |
4128 |
if (read_write == I2C_SMBUS_WRITE) { |
4129 |
outb_p(tmp_data.byte, adapdata->addr + SMBHSTDAT); |
4130 |
outb_p(NCT6793D_WRITE_BYTE, adapdata->addr + SMBHSTCMD); |
4131 |
} else { |
4132 |
outb_p(NCT6793D_READ_BYTE, adapdata->addr + SMBHSTCMD); |
4133 |
} |
4134 |
break; |
4135 |
case I2C_SMBUS_WORD_DATA: |
4136 |
outb_p((addr << 1) | read_write, |
4137 |
adapdata->addr + SMBHSTADD); |
4138 |
outb_p(command, adapdata->addr + SMBHSTIDX); |
4139 |
if (read_write == I2C_SMBUS_WRITE) { |
4140 |
outb_p(data->word & 0xff, adapdata->addr + SMBHSTDAT); |
4141 |
outb_p((data->word & 0xff00) >> 8, adapdata->addr + SMBHSTDAT); |
4142 |
outb_p(NCT6793D_WRITE_WORD, adapdata->addr + SMBHSTCMD); |
4143 |
} else { |
4144 |
outb_p(NCT6793D_READ_WORD, adapdata->addr + SMBHSTCMD); |
4145 |
} |
4146 |
break; |
4147 |
case I2C_SMBUS_BLOCK_DATA: |
4148 |
outb_p((addr << 1) | read_write, |
4149 |
adapdata->addr + SMBHSTADD); |
4150 |
outb_p(command, adapdata->addr + SMBHSTIDX); |
4151 |
if (read_write == I2C_SMBUS_WRITE) { |
4152 |
len = data->block[0]; |
4153 |
|
4154 |
if (len == 0 || len > I2C_SMBUS_BLOCK_MAX) { |
4155 |
ret = -EINVAL; |
4156 |
goto abort; |
4157 |
} |
4158 |
|
4159 |
outb_p(len, adapdata->addr + SMBBLKSZ); |
4160 |
|
4161 |
cnt = 1; |
4162 |
if (len >= 4) { |
4163 |
for (i = cnt; i <= 4; i++) |
4164 |
outb_p(data->block[i], adapdata->addr + SMBHSTDAT); |
4165 |
|
4166 |
len -= 4; |
4167 |
cnt += 4; |
4168 |
} else { |
4169 |
for (i = cnt; i <= len; i++) |
4170 |
outb_p(data->block[i], adapdata->addr + SMBHSTDAT); |
4171 |
|
4172 |
len = 0; |
4173 |
} |
4174 |
|
4175 |
outb_p(NCT6793D_WRITE_BLOCK, adapdata->addr + SMBHSTCMD); |
4176 |
} else { |
4177 |
ret = -EOPNOTSUPP; |
4178 |
goto abort; |
4179 |
} |
4180 |
break; |
4181 |
default: |
4182 |
dev_warn(&adap->dev, "Unsupported transaction %d\n", size); |
4183 |
ret = -EOPNOTSUPP; |
4184 |
goto abort; |
4185 |
} |
4186 |
|
4187 |
outb_p(NCT6793D_MANUAL_START, adapdata->addr + SMBHSTCTL); |
4188 |
|
4189 |
while ((size == I2C_SMBUS_BLOCK_DATA) && (len > 0)) { |
4190 |
if (read_write == I2C_SMBUS_WRITE) { |
4191 |
timeout = 0; |
4192 |
|
4193 |
while ((inb_p(adapdata->addr + SMBHSTSTS) & NCT6793D_FIFO_EMPTY) == 0) { |
4194 |
if (timeout > MAX_RETRIES) { |
4195 |
ret = -ETIMEDOUT; |
4196 |
goto abort; |
4197 |
} |
4198 |
|
4199 |
usleep_range(250, 500); |
4200 |
timeout++; |
4201 |
} |
4202 |
|
4203 |
//Load more bytes into FIFO |
4204 |
if (len >= 4) { |
4205 |
for (i = cnt; i <= (cnt + 4); i++) |
4206 |
outb_p(data->block[i], adapdata->addr + SMBHSTDAT); |
4207 |
|
4208 |
len -= 4; |
4209 |
cnt += 4; |
4210 |
} else { |
4211 |
for (i = cnt; i <= (cnt + len); i++) |
4212 |
outb_p(data->block[i], adapdata->addr + SMBHSTDAT); |
4213 |
|
4214 |
len = 0; |
4215 |
} |
4216 |
} else { |
4217 |
ret = -EOPNOTSUPP; |
4218 |
goto abort; |
4219 |
} |
4220 |
} |
4221 |
|
4222 |
//wait for manual mode to complete |
4223 |
timeout = 0; |
4224 |
while ((inb_p(adapdata->addr + SMBHSTSTS) & NCT6793D_MANUAL_ACTIVE) != 0) { |
4225 |
if (timeout > MAX_RETRIES) { |
4226 |
ret = -ETIMEDOUT; |
4227 |
goto abort; |
4228 |
} |
4229 |
|
4230 |
usleep_range(250, 500); |
4231 |
timeout++; |
4232 |
} |
4233 |
|
4234 |
if ((inb_p(adapdata->addr + SMBHSTERR) & NCT6793D_NO_ACK) != 0) { |
4235 |
ret = -ENXIO; |
4236 |
goto abort; |
4237 |
} |
4238 |
|
4239 |
if (read_write == I2C_SMBUS_WRITE || size == I2C_SMBUS_QUICK) |
4240 |
goto abort; |
4241 |
|
4242 |
switch (size) { |
4243 |
case I2C_SMBUS_QUICK: |
4244 |
case I2C_SMBUS_BYTE_DATA: |
4245 |
data->byte = inb_p(adapdata->addr + SMBHSTDAT); |
4246 |
break; |
4247 |
case I2C_SMBUS_WORD_DATA: |
4248 |
data->word = inb_p(adapdata->addr + SMBHSTDAT) + |
4249 |
(inb_p(adapdata->addr + SMBHSTDAT) << 8); |
4250 |
break; |
4251 |
} |
4252 |
|
4253 |
abort: |
4254 |
adapdata->unlock(adapdata, &adap->dev); |
4255 |
return ret; |
4256 |
} |
4257 |
|
4258 |
static u32 nct6775_i2c_func(struct i2c_adapter *adapter) |
4259 |
{ |
4260 |
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | |
4261 |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | |
4262 |
I2C_FUNC_SMBUS_BLOCK_DATA; |
4263 |
} |
4264 |
|
4265 |
static const struct i2c_algorithm smbus_algorithm = { |
4266 |
.smbus_xfer = nct6775_i2c_access, |
4267 |
.functionality = nct6775_i2c_func, |
4268 |
}; |
4269 |
|
4270 |
static int nct6775_i2c_add_adapter(acpi_handle acpi_wmi_mutex, struct nct6775_data *adapdata, |
4271 |
struct i2c_adapter **padap) |
4272 |
{ |
4273 |
struct i2c_adapter *adap; |
4274 |
int retval; |
4275 |
|
4276 |
adap = kzalloc(sizeof(*adap), GFP_KERNEL); |
4277 |
if (!adap) |
4278 |
return -ENOMEM; |
4279 |
|
4280 |
adap->owner = THIS_MODULE; |
4281 |
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; |
4282 |
adap->algo = &smbus_algorithm; |
4283 |
|
4284 |
snprintf(adap->name, sizeof(adap->name), |
4285 |
"SMBus NCT67xx adapter at %04x", adapdata->addr); |
4286 |
|
4287 |
i2c_set_adapdata(adap, adapdata); |
4288 |
|
4289 |
retval = i2c_add_adapter(adap); |
4290 |
if (retval) { |
4291 |
kfree(adap); |
4292 |
return retval; |
4293 |
} |
4294 |
|
4295 |
*padap = adap; |
4296 |
return 0; |
4297 |
} |
4298 |
|
4299 |
static void nct6775_i2c_remove_adapter(struct i2c_adapter *adap) |
4300 |
{ |
4301 |
i2c_del_adapter(adap); |
4302 |
kfree(adap); |
4303 |
} |
4304 |
|
3791 |
static int nct6775_probe(struct platform_device *pdev) |
4305 |
static int nct6775_probe(struct platform_device *pdev) |
3792 |
{ |
4306 |
{ |
3793 |
struct device *dev = &pdev->dev; |
4307 |
struct device *dev = &pdev->dev; |
Lines 3805-3814
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
3805 |
struct device *hwmon_dev; |
4319 |
struct device *hwmon_dev; |
3806 |
int num_attr_groups = 0; |
4320 |
int num_attr_groups = 0; |
3807 |
|
4321 |
|
3808 |
res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
4322 |
if (sio_data->access == access_direct) { |
3809 |
if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, |
4323 |
res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
3810 |
DRVNAME)) |
4324 |
if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH, |
3811 |
return -EBUSY; |
4325 |
DRVNAME)) |
|
|
4326 |
return -EBUSY; |
4327 |
} |
3812 |
|
4328 |
|
3813 |
data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data), |
4329 |
data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data), |
3814 |
GFP_KERNEL); |
4330 |
GFP_KERNEL); |
Lines 3817-3828
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
3817 |
|
4333 |
|
3818 |
data->kind = sio_data->kind; |
4334 |
data->kind = sio_data->kind; |
3819 |
data->sioreg = sio_data->sioreg; |
4335 |
data->sioreg = sio_data->sioreg; |
3820 |
data->addr = res->start; |
4336 |
|
3821 |
mutex_init(&data->update_lock); |
4337 |
if (sio_data->access == access_direct) { |
|
|
4338 |
data->addr = res->start; |
4339 |
data->read_value = nct6775_read_value; |
4340 |
data->write_value = nct6775_write_value; |
4341 |
} else { |
4342 |
data->read_value = nct6775_wmi_read_value; |
4343 |
data->write_value = nct6775_wmi_write_value; |
4344 |
} |
4345 |
|
4346 |
if (sio_data->acpi_wmi_mutex) { |
4347 |
data->mlock.acpi_wmi_mutex = sio_data->acpi_wmi_mutex; |
4348 |
data->lock = nct6775_wmi_lock; |
4349 |
data->unlock = nct6775_wmi_unlock; |
4350 |
} else { |
4351 |
mutex_init(&data->mlock.update_lock); |
4352 |
data->lock = nct6775_lock; |
4353 |
data->unlock = nct6775_unlock; |
4354 |
} |
4355 |
|
3822 |
data->name = nct6775_device_names[data->kind]; |
4356 |
data->name = nct6775_device_names[data->kind]; |
3823 |
data->bank = 0xff; /* Force initial bank selection */ |
4357 |
data->bank = 0xff; /* Force initial bank selection */ |
3824 |
platform_set_drvdata(pdev, data); |
4358 |
platform_set_drvdata(pdev, data); |
3825 |
|
4359 |
|
|
|
4360 |
if (sio_data->access == access_direct) { |
4361 |
switch (sio_data->kind) { |
4362 |
case nct6791: |
4363 |
case nct6792: |
4364 |
case nct6793: |
4365 |
case nct6795: |
4366 |
case nct6796: |
4367 |
case nct6798: |
4368 |
nct6775_i2c_add_adapter(data->mlock.acpi_wmi_mutex, data, |
4369 |
&data->i2c_adapter); |
4370 |
break; |
4371 |
default: |
4372 |
pr_err("i2c have not found"); |
4373 |
} |
4374 |
} |
4375 |
|
3826 |
switch (data->kind) { |
4376 |
switch (data->kind) { |
3827 |
case nct6106: |
4377 |
case nct6106: |
3828 |
data->in_num = 9; |
4378 |
data->in_num = 9; |
Lines 4337-4343
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4337 |
if (reg_temp[i] == 0) |
4887 |
if (reg_temp[i] == 0) |
4338 |
continue; |
4888 |
continue; |
4339 |
|
4889 |
|
4340 |
src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; |
4890 |
src = data->read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; |
4341 |
if (!src || (mask & BIT(src))) |
4891 |
if (!src || (mask & BIT(src))) |
4342 |
available |= BIT(i); |
4892 |
available |= BIT(i); |
4343 |
|
4893 |
|
Lines 4357-4363
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4357 |
if (reg_temp[i] == 0) |
4907 |
if (reg_temp[i] == 0) |
4358 |
continue; |
4908 |
continue; |
4359 |
|
4909 |
|
4360 |
src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; |
4910 |
src = data->read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f; |
4361 |
if (!src || (mask & BIT(src))) |
4911 |
if (!src || (mask & BIT(src))) |
4362 |
continue; |
4912 |
continue; |
4363 |
|
4913 |
|
Lines 4417-4423
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4417 |
if (reg_temp_mon[i] == 0) |
4967 |
if (reg_temp_mon[i] == 0) |
4418 |
continue; |
4968 |
continue; |
4419 |
|
4969 |
|
4420 |
src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f; |
4970 |
src = data->read_value(data, data->REG_TEMP_SEL[i]) & 0x1f; |
4421 |
if (!src) |
4971 |
if (!src) |
4422 |
continue; |
4972 |
continue; |
4423 |
|
4973 |
|
Lines 4502-4512
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4502 |
/* Initialize the chip */ |
5052 |
/* Initialize the chip */ |
4503 |
nct6775_init_device(data); |
5053 |
nct6775_init_device(data); |
4504 |
|
5054 |
|
4505 |
err = superio_enter(sio_data->sioreg); |
5055 |
err = sio_data->sio_enter(sio_data); |
4506 |
if (err) |
5056 |
if (err) |
4507 |
return err; |
5057 |
return err; |
4508 |
|
5058 |
|
4509 |
cr2a = superio_inb(sio_data->sioreg, 0x2a); |
5059 |
cr2a = sio_data->sio_inb(sio_data, 0x2a); |
4510 |
switch (data->kind) { |
5060 |
switch (data->kind) { |
4511 |
case nct6775: |
5061 |
case nct6775: |
4512 |
data->have_vid = (cr2a & 0x40); |
5062 |
data->have_vid = (cr2a & 0x40); |
Lines 4532-4548
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4532 |
* We can get the VID input values directly at logical device D 0xe3. |
5082 |
* We can get the VID input values directly at logical device D 0xe3. |
4533 |
*/ |
5083 |
*/ |
4534 |
if (data->have_vid) { |
5084 |
if (data->have_vid) { |
4535 |
superio_select(sio_data->sioreg, NCT6775_LD_VID); |
5085 |
sio_data->sio_select(sio_data, NCT6775_LD_VID); |
4536 |
data->vid = superio_inb(sio_data->sioreg, 0xe3); |
5086 |
data->vid = sio_data->sio_inb(sio_data, 0xe3); |
4537 |
data->vrm = vid_which_vrm(); |
5087 |
data->vrm = vid_which_vrm(); |
4538 |
} |
5088 |
} |
4539 |
|
5089 |
|
4540 |
if (fan_debounce) { |
5090 |
if (fan_debounce) { |
4541 |
u8 tmp; |
5091 |
u8 tmp; |
4542 |
|
5092 |
|
4543 |
superio_select(sio_data->sioreg, NCT6775_LD_HWM); |
5093 |
sio_data->sio_select(sio_data, NCT6775_LD_HWM); |
4544 |
tmp = superio_inb(sio_data->sioreg, |
5094 |
tmp = sio_data->sio_inb(sio_data, |
4545 |
NCT6775_REG_CR_FAN_DEBOUNCE); |
5095 |
NCT6775_REG_CR_FAN_DEBOUNCE); |
4546 |
switch (data->kind) { |
5096 |
switch (data->kind) { |
4547 |
case nct6106: |
5097 |
case nct6106: |
4548 |
case nct6116: |
5098 |
case nct6116: |
Lines 4565-4579
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4565 |
tmp |= 0x7e; |
5115 |
tmp |= 0x7e; |
4566 |
break; |
5116 |
break; |
4567 |
} |
5117 |
} |
4568 |
superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE, |
5118 |
sio_data->sio_outb(sio_data, NCT6775_REG_CR_FAN_DEBOUNCE, |
4569 |
tmp); |
5119 |
tmp); |
4570 |
dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n", |
5120 |
dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n", |
4571 |
data->name); |
5121 |
data->name); |
4572 |
} |
5122 |
} |
4573 |
|
5123 |
|
4574 |
nct6775_check_fan_inputs(data); |
5124 |
nct6775_check_fan_inputs(data, sio_data); |
4575 |
|
5125 |
|
4576 |
superio_exit(sio_data->sioreg); |
5126 |
sio_data->sio_exit(sio_data); |
4577 |
|
5127 |
|
4578 |
/* Read fan clock dividers immediately */ |
5128 |
/* Read fan clock dividers immediately */ |
4579 |
nct6775_init_fan_common(dev, data); |
5129 |
nct6775_init_fan_common(dev, data); |
Lines 4613-4641
static int nct6775_probe(struct platform_device *pdev)
Link Here
|
4613 |
return PTR_ERR_OR_ZERO(hwmon_dev); |
5163 |
return PTR_ERR_OR_ZERO(hwmon_dev); |
4614 |
} |
5164 |
} |
4615 |
|
5165 |
|
4616 |
static void nct6791_enable_io_mapping(int sioaddr) |
5166 |
static int nct6775_remove(struct platform_device *pdev) |
|
|
5167 |
{ |
5168 |
struct nct6775_data *data = platform_get_drvdata(pdev); |
5169 |
|
5170 |
if (data->i2c_adapter) |
5171 |
nct6775_i2c_remove_adapter(data->i2c_adapter); |
5172 |
|
5173 |
return 0; |
5174 |
} |
5175 |
|
5176 |
static void nct6791_enable_io_mapping(struct nct6775_sio_data *sio_data) |
4617 |
{ |
5177 |
{ |
4618 |
int val; |
5178 |
int val; |
4619 |
|
5179 |
|
4620 |
val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE); |
5180 |
val = sio_data->sio_inb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE); |
4621 |
if (val & 0x10) { |
5181 |
if (val & 0x10) { |
4622 |
pr_info("Enabling hardware monitor logical device mappings.\n"); |
5182 |
pr_info("Enabling hardware monitor logical device mappings.\n"); |
4623 |
superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE, |
5183 |
sio_data->sio_outb(sio_data, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE, |
4624 |
val & ~0x10); |
5184 |
val & ~0x10); |
4625 |
} |
5185 |
} |
4626 |
} |
5186 |
} |
4627 |
|
5187 |
|
4628 |
static int __maybe_unused nct6775_suspend(struct device *dev) |
5188 |
static int __maybe_unused nct6775_suspend(struct device *dev) |
4629 |
{ |
5189 |
{ |
4630 |
struct nct6775_data *data = nct6775_update_device(dev); |
5190 |
struct nct6775_data *data = nct6775_update_device(dev); |
|
|
5191 |
int err; |
5192 |
|
5193 |
err = data->lock(data); |
5194 |
if (err) |
5195 |
return err; |
4631 |
|
5196 |
|
4632 |
mutex_lock(&data->update_lock); |
5197 |
data->vbat = data->read_value(data, data->REG_VBAT); |
4633 |
data->vbat = nct6775_read_value(data, data->REG_VBAT); |
|
|
4634 |
if (data->kind == nct6775) { |
5198 |
if (data->kind == nct6775) { |
4635 |
data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1); |
5199 |
data->fandiv1 = data->read_value(data, NCT6775_REG_FANDIV1); |
4636 |
data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2); |
5200 |
data->fandiv2 = data->read_value(data, NCT6775_REG_FANDIV2); |
4637 |
} |
5201 |
} |
4638 |
mutex_unlock(&data->update_lock); |
5202 |
data->unlock(data, dev); |
4639 |
|
5203 |
|
4640 |
return 0; |
5204 |
return 0; |
4641 |
} |
5205 |
} |
Lines 4643-4689
static int __maybe_unused nct6775_suspend(struct device *dev)
Link Here
|
4643 |
static int __maybe_unused nct6775_resume(struct device *dev) |
5207 |
static int __maybe_unused nct6775_resume(struct device *dev) |
4644 |
{ |
5208 |
{ |
4645 |
struct nct6775_data *data = dev_get_drvdata(dev); |
5209 |
struct nct6775_data *data = dev_get_drvdata(dev); |
4646 |
int sioreg = data->sioreg; |
5210 |
struct nct6775_sio_data *sio_data = dev_get_platdata(dev); |
4647 |
int i, j, err = 0; |
5211 |
int i, j, err; |
4648 |
u8 reg; |
5212 |
u8 reg; |
4649 |
|
5213 |
|
4650 |
mutex_lock(&data->update_lock); |
5214 |
err = data->lock(data); |
|
|
5215 |
if (err) |
5216 |
return err; |
5217 |
|
4651 |
data->bank = 0xff; /* Force initial bank selection */ |
5218 |
data->bank = 0xff; /* Force initial bank selection */ |
4652 |
|
5219 |
|
4653 |
err = superio_enter(sioreg); |
5220 |
err = sio_data->sio_enter(sio_data); |
4654 |
if (err) |
5221 |
if (err) |
4655 |
goto abort; |
5222 |
goto abort; |
4656 |
|
5223 |
|
4657 |
superio_select(sioreg, NCT6775_LD_HWM); |
5224 |
sio_data->sio_select(sio_data, NCT6775_LD_HWM); |
4658 |
reg = superio_inb(sioreg, SIO_REG_ENABLE); |
5225 |
reg = sio_data->sio_inb(sio_data, SIO_REG_ENABLE); |
4659 |
if (reg != data->sio_reg_enable) |
5226 |
if (reg != data->sio_reg_enable) |
4660 |
superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable); |
5227 |
sio_data->sio_outb(sio_data, SIO_REG_ENABLE, data->sio_reg_enable); |
4661 |
|
5228 |
|
4662 |
if (data->kind == nct6791 || data->kind == nct6792 || |
5229 |
if (data->kind == nct6791 || data->kind == nct6792 || |
4663 |
data->kind == nct6793 || data->kind == nct6795 || |
5230 |
data->kind == nct6793 || data->kind == nct6795 || |
4664 |
data->kind == nct6796 || data->kind == nct6797 || |
5231 |
data->kind == nct6796 || data->kind == nct6797 || |
4665 |
data->kind == nct6798) |
5232 |
data->kind == nct6798) |
4666 |
nct6791_enable_io_mapping(sioreg); |
5233 |
nct6791_enable_io_mapping(sio_data); |
4667 |
|
5234 |
|
4668 |
superio_exit(sioreg); |
5235 |
sio_data->sio_exit(sio_data); |
4669 |
|
5236 |
|
4670 |
/* Restore limits */ |
5237 |
/* Restore limits */ |
4671 |
for (i = 0; i < data->in_num; i++) { |
5238 |
for (i = 0; i < data->in_num; i++) { |
4672 |
if (!(data->have_in & BIT(i))) |
5239 |
if (!(data->have_in & BIT(i))) |
4673 |
continue; |
5240 |
continue; |
4674 |
|
5241 |
|
4675 |
nct6775_write_value(data, data->REG_IN_MINMAX[0][i], |
5242 |
data->write_value(data, data->REG_IN_MINMAX[0][i], |
4676 |
data->in[i][1]); |
5243 |
data->in[i][1]); |
4677 |
nct6775_write_value(data, data->REG_IN_MINMAX[1][i], |
5244 |
data->write_value(data, data->REG_IN_MINMAX[1][i], |
4678 |
data->in[i][2]); |
5245 |
data->in[i][2]); |
4679 |
} |
5246 |
} |
4680 |
|
5247 |
|
4681 |
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { |
5248 |
for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) { |
4682 |
if (!(data->has_fan_min & BIT(i))) |
5249 |
if (!(data->has_fan_min & BIT(i))) |
4683 |
continue; |
5250 |
continue; |
4684 |
|
5251 |
|
4685 |
nct6775_write_value(data, data->REG_FAN_MIN[i], |
5252 |
data->write_value(data, data->REG_FAN_MIN[i], |
4686 |
data->fan_min[i]); |
5253 |
data->fan_min[i]); |
4687 |
} |
5254 |
} |
4688 |
|
5255 |
|
4689 |
for (i = 0; i < NUM_TEMP; i++) { |
5256 |
for (i = 0; i < NUM_TEMP; i++) { |
Lines 4697-4712
static int __maybe_unused nct6775_resume(struct device *dev)
Link Here
|
4697 |
} |
5264 |
} |
4698 |
|
5265 |
|
4699 |
/* Restore other settings */ |
5266 |
/* Restore other settings */ |
4700 |
nct6775_write_value(data, data->REG_VBAT, data->vbat); |
5267 |
data->write_value(data, data->REG_VBAT, data->vbat); |
4701 |
if (data->kind == nct6775) { |
5268 |
if (data->kind == nct6775) { |
4702 |
nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1); |
5269 |
data->write_value(data, NCT6775_REG_FANDIV1, data->fandiv1); |
4703 |
nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); |
5270 |
data->write_value(data, NCT6775_REG_FANDIV2, data->fandiv2); |
4704 |
} |
5271 |
} |
4705 |
|
5272 |
|
4706 |
abort: |
5273 |
abort: |
4707 |
/* Force re-reading all values */ |
5274 |
/* Force re-reading all values */ |
4708 |
data->valid = false; |
5275 |
data->valid = false; |
4709 |
mutex_unlock(&data->update_lock); |
5276 |
data->unlock(data, dev); |
4710 |
|
5277 |
|
4711 |
return err; |
5278 |
return err; |
4712 |
} |
5279 |
} |
Lines 4719-4724
static struct platform_driver nct6775_driver = {
Link Here
|
4719 |
.pm = &nct6775_dev_pm_ops, |
5286 |
.pm = &nct6775_dev_pm_ops, |
4720 |
}, |
5287 |
}, |
4721 |
.probe = nct6775_probe, |
5288 |
.probe = nct6775_probe, |
|
|
5289 |
.remove = nct6775_remove, |
4722 |
}; |
5290 |
}; |
4723 |
|
5291 |
|
4724 |
/* nct6775_find() looks for a '627 in the Super-I/O config space */ |
5292 |
/* nct6775_find() looks for a '627 in the Super-I/O config space */ |
Lines 4728-4739
static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
Link Here
|
4728 |
int err; |
5296 |
int err; |
4729 |
int addr; |
5297 |
int addr; |
4730 |
|
5298 |
|
4731 |
err = superio_enter(sioaddr); |
5299 |
sio_data->access = access_direct; |
|
|
5300 |
sio_data->sioreg = sioaddr; |
5301 |
|
5302 |
err = sio_data->sio_enter(sio_data); |
4732 |
if (err) |
5303 |
if (err) |
4733 |
return err; |
5304 |
return err; |
4734 |
|
5305 |
|
4735 |
val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | |
5306 |
val = (sio_data->sio_inb(sio_data, SIO_REG_DEVID) << 8) | |
4736 |
superio_inb(sioaddr, SIO_REG_DEVID + 1); |
5307 |
sio_data->sio_inb(sio_data, SIO_REG_DEVID + 1); |
4737 |
if (force_id && val != 0xffff) |
5308 |
if (force_id && val != 0xffff) |
4738 |
val = force_id; |
5309 |
val = force_id; |
4739 |
|
5310 |
|
Lines 4777-4814
static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
Link Here
|
4777 |
default: |
5348 |
default: |
4778 |
if (val != 0xffff) |
5349 |
if (val != 0xffff) |
4779 |
pr_debug("unsupported chip ID: 0x%04x\n", val); |
5350 |
pr_debug("unsupported chip ID: 0x%04x\n", val); |
4780 |
superio_exit(sioaddr); |
5351 |
sio_data->sio_exit(sio_data); |
4781 |
return -ENODEV; |
5352 |
return -ENODEV; |
4782 |
} |
5353 |
} |
4783 |
|
5354 |
|
4784 |
/* We have a known chip, find the HWM I/O address */ |
5355 |
/* We have a known chip, find the HWM I/O address */ |
4785 |
superio_select(sioaddr, NCT6775_LD_HWM); |
5356 |
sio_data->sio_select(sio_data, NCT6775_LD_HWM); |
4786 |
val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8) |
5357 |
val = (sio_data->sio_inb(sio_data, SIO_REG_ADDR) << 8) |
4787 |
| superio_inb(sioaddr, SIO_REG_ADDR + 1); |
5358 |
| sio_data->sio_inb(sio_data, SIO_REG_ADDR + 1); |
4788 |
addr = val & IOREGION_ALIGNMENT; |
5359 |
addr = val & IOREGION_ALIGNMENT; |
4789 |
if (addr == 0) { |
5360 |
if (addr == 0) { |
4790 |
pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n"); |
5361 |
pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n"); |
4791 |
superio_exit(sioaddr); |
5362 |
sio_data->sio_exit(sio_data); |
4792 |
return -ENODEV; |
5363 |
return -ENODEV; |
4793 |
} |
5364 |
} |
4794 |
|
5365 |
|
4795 |
/* Activate logical device if needed */ |
5366 |
/* Activate logical device if needed */ |
4796 |
val = superio_inb(sioaddr, SIO_REG_ENABLE); |
5367 |
val = sio_data->sio_inb(sio_data, SIO_REG_ENABLE); |
4797 |
if (!(val & 0x01)) { |
5368 |
if (!(val & 0x01)) { |
4798 |
pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); |
5369 |
pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n"); |
4799 |
superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01); |
5370 |
sio_data->sio_outb(sio_data, SIO_REG_ENABLE, val | 0x01); |
4800 |
} |
5371 |
} |
4801 |
|
5372 |
|
4802 |
if (sio_data->kind == nct6791 || sio_data->kind == nct6792 || |
5373 |
if (sio_data->kind == nct6791 || sio_data->kind == nct6792 || |
4803 |
sio_data->kind == nct6793 || sio_data->kind == nct6795 || |
5374 |
sio_data->kind == nct6793 || sio_data->kind == nct6795 || |
4804 |
sio_data->kind == nct6796 || sio_data->kind == nct6797 || |
5375 |
sio_data->kind == nct6796 || sio_data->kind == nct6797 || |
4805 |
sio_data->kind == nct6798) |
5376 |
sio_data->kind == nct6798) |
4806 |
nct6791_enable_io_mapping(sioaddr); |
5377 |
nct6791_enable_io_mapping(sio_data); |
4807 |
|
5378 |
|
4808 |
superio_exit(sioaddr); |
5379 |
sio_data->sio_exit(sio_data); |
4809 |
pr_info("Found %s or compatible chip at %#x:%#x\n", |
5380 |
pr_info("Found %s or compatible chip at %#x:%#x\n", |
4810 |
nct6775_sio_names[sio_data->kind], sioaddr, addr); |
5381 |
nct6775_sio_names[sio_data->kind], sioaddr, addr); |
4811 |
sio_data->sioreg = sioaddr; |
|
|
4812 |
|
5382 |
|
4813 |
return addr; |
5383 |
return addr; |
4814 |
} |
5384 |
} |
Lines 4821-4826
static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
Link Here
|
4821 |
*/ |
5391 |
*/ |
4822 |
static struct platform_device *pdev[2]; |
5392 |
static struct platform_device *pdev[2]; |
4823 |
|
5393 |
|
|
|
5394 |
struct acpi_board_info { |
5395 |
char *acpi_mutex_path; |
5396 |
}; |
5397 |
|
5398 |
#define DMI_ASUS_BOARD_INFO(name, mutex_path) \ |
5399 |
static struct acpi_board_info name = { \ |
5400 |
.acpi_mutex_path = mutex_path, \ |
5401 |
} |
5402 |
|
5403 |
DMI_ASUS_BOARD_INFO(acpi_board_MAXIMUS_VII_HERO, "\\_SB_.PCI0.LPCB.SIO1.MUT0"); |
5404 |
DMI_ASUS_BOARD_INFO(acpi_board_ROG_STRIX_B550_E_GAMING, "\\_SB.PCI0.SBRG.SIO1.MUT0"); |
5405 |
|
5406 |
#define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, info) { \ |
5407 |
.matches = { \ |
5408 |
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), \ |
5409 |
DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ |
5410 |
}, \ |
5411 |
.driver_data = info, \ |
5412 |
} |
5413 |
|
5414 |
static const struct dmi_system_id asus_wmi_info_table[] = { |
5415 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("MAXIMUS VII HERO", &acpi_board_MAXIMUS_VII_HERO), |
5416 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME B360-PLUS", NULL), |
5417 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME B460-PLUS", NULL), |
5418 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME B550M-A (WI-FI)", NULL), |
5419 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", NULL), |
5420 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE", NULL), |
5421 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", NULL), |
5422 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO", NULL), |
5423 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA", NULL), |
5424 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO", NULL), |
5425 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT", NULL), |
5426 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING", |
5427 |
&acpi_board_ROG_STRIX_B550_E_GAMING), |
5428 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-F GAMING", NULL), |
5429 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-F GAMING (WI-FI)", NULL), |
5430 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING", NULL), |
5431 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING", NULL), |
5432 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z390-E GAMING", NULL), |
5433 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z490-I GAMING", NULL), |
5434 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING B550-PLUS", NULL), |
5435 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING B550-PRO", NULL), |
5436 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING B550M-PLUS", NULL), |
5437 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING B550M-PLUS (WI-FI)", NULL), |
5438 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X570-PLUS", NULL), |
5439 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X570-PLUS (WI-FI)", NULL), |
5440 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING X570-PRO (WI-FI)", NULL), |
5441 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING Z490-PLUS", NULL), |
5442 |
DMI_EXACT_MATCH_ASUS_BOARD_NAME("TUF GAMING Z490-PLUS (WI-FI)", NULL), |
5443 |
{} |
5444 |
}; |
5445 |
MODULE_DEVICE_TABLE(dmi, asus_wmi_info_table); |
5446 |
|
4824 |
static int __init sensors_nct6775_init(void) |
5447 |
static int __init sensors_nct6775_init(void) |
4825 |
{ |
5448 |
{ |
4826 |
int i, err; |
5449 |
int i, err; |
Lines 4829-4839
static int __init sensors_nct6775_init(void)
Link Here
|
4829 |
struct resource res; |
5452 |
struct resource res; |
4830 |
struct nct6775_sio_data sio_data; |
5453 |
struct nct6775_sio_data sio_data; |
4831 |
int sioaddr[2] = { 0x2e, 0x4e }; |
5454 |
int sioaddr[2] = { 0x2e, 0x4e }; |
|
|
5455 |
enum sensor_access access = access_direct; |
5456 |
const struct dmi_system_id *dmi_id; |
5457 |
struct acpi_board_info *board_info; |
5458 |
acpi_handle acpi_wmi_mutex = NULL; |
5459 |
acpi_status status; |
5460 |
u8 tmp = 0; |
4832 |
|
5461 |
|
4833 |
err = platform_driver_register(&nct6775_driver); |
5462 |
err = platform_driver_register(&nct6775_driver); |
4834 |
if (err) |
5463 |
if (err) |
4835 |
return err; |
5464 |
return err; |
4836 |
|
5465 |
|
|
|
5466 |
dmi_id = dmi_first_match(asus_wmi_info_table); |
5467 |
if (dmi_id) { |
5468 |
/* if reading chip ID via WMI succeeds, use WMI */ |
5469 |
if (!nct6775_asuswmi_read(0, NCT6775_PORT_CHIPID, &tmp) && |
5470 |
tmp) { |
5471 |
pr_info("Using Asus WMI to access %#x chip.\n", tmp); |
5472 |
access = access_asuswmi; |
5473 |
} else { |
5474 |
pr_err("Can't read chip ID by Asus WMI.\n"); |
5475 |
} |
5476 |
|
5477 |
if (dmi_id->driver_data) { |
5478 |
board_info = dmi_id->driver_data; |
5479 |
if (board_info->acpi_mutex_path) { |
5480 |
status = acpi_get_handle(NULL, board_info->acpi_mutex_path, |
5481 |
&acpi_wmi_mutex); |
5482 |
if (!ACPI_FAILURE(status)) { |
5483 |
pr_info("Using Asus WMI mutex: %s\n", |
5484 |
board_info->acpi_mutex_path); |
5485 |
access = access_direct; |
5486 |
} |
5487 |
} |
5488 |
} |
5489 |
} |
5490 |
|
4837 |
/* |
5491 |
/* |
4838 |
* initialize sio_data->kind and sio_data->sioreg. |
5492 |
* initialize sio_data->kind and sio_data->sioreg. |
4839 |
* |
5493 |
* |
Lines 4842-4853
static int __init sensors_nct6775_init(void)
Link Here
|
4842 |
* nct6775 hardware monitor, and call probe() |
5496 |
* nct6775 hardware monitor, and call probe() |
4843 |
*/ |
5497 |
*/ |
4844 |
for (i = 0; i < ARRAY_SIZE(pdev); i++) { |
5498 |
for (i = 0; i < ARRAY_SIZE(pdev); i++) { |
|
|
5499 |
sio_data.sio_outb = superio_outb; |
5500 |
sio_data.sio_inb = superio_inb; |
5501 |
sio_data.sio_select = superio_select; |
5502 |
sio_data.sio_enter = superio_enter; |
5503 |
sio_data.sio_exit = superio_exit; |
5504 |
|
4845 |
address = nct6775_find(sioaddr[i], &sio_data); |
5505 |
address = nct6775_find(sioaddr[i], &sio_data); |
4846 |
if (address <= 0) |
5506 |
if (address <= 0) |
4847 |
continue; |
5507 |
continue; |
4848 |
|
5508 |
|
4849 |
found = true; |
5509 |
found = true; |
4850 |
|
5510 |
|
|
|
5511 |
sio_data.access = access; |
5512 |
sio_data.acpi_wmi_mutex = acpi_wmi_mutex; |
5513 |
|
5514 |
if (access == access_asuswmi) { |
5515 |
sio_data.sio_outb = superio_wmi_outb; |
5516 |
sio_data.sio_inb = superio_wmi_inb; |
5517 |
sio_data.sio_select = superio_wmi_select; |
5518 |
sio_data.sio_enter = superio_wmi_enter; |
5519 |
sio_data.sio_exit = superio_wmi_exit; |
5520 |
} |
5521 |
|
4851 |
pdev[i] = platform_device_alloc(DRVNAME, address); |
5522 |
pdev[i] = platform_device_alloc(DRVNAME, address); |
4852 |
if (!pdev[i]) { |
5523 |
if (!pdev[i]) { |
4853 |
err = -ENOMEM; |
5524 |
err = -ENOMEM; |
Lines 4859-4881
static int __init sensors_nct6775_init(void)
Link Here
|
4859 |
if (err) |
5530 |
if (err) |
4860 |
goto exit_device_put; |
5531 |
goto exit_device_put; |
4861 |
|
5532 |
|
4862 |
memset(&res, 0, sizeof(res)); |
5533 |
if (sio_data.access == access_direct) { |
4863 |
res.name = DRVNAME; |
5534 |
memset(&res, 0, sizeof(res)); |
4864 |
res.start = address + IOREGION_OFFSET; |
5535 |
res.name = DRVNAME; |
4865 |
res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; |
5536 |
res.start = address + IOREGION_OFFSET; |
4866 |
res.flags = IORESOURCE_IO; |
5537 |
res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1; |
|
|
5538 |
res.flags = IORESOURCE_IO; |
5539 |
|
5540 |
if (!acpi_wmi_mutex) { |
5541 |
err = acpi_check_resource_conflict(&res); |
5542 |
if (err) { |
5543 |
platform_device_put(pdev[i]); |
5544 |
pdev[i] = NULL; |
5545 |
continue; |
5546 |
} |
5547 |
} |
4867 |
|
5548 |
|
4868 |
err = acpi_check_resource_conflict(&res); |
5549 |
err = platform_device_add_resources(pdev[i], &res, 1); |
4869 |
if (err) { |
5550 |
if (err) |
4870 |
platform_device_put(pdev[i]); |
5551 |
goto exit_device_put; |
4871 |
pdev[i] = NULL; |
|
|
4872 |
continue; |
4873 |
} |
5552 |
} |
4874 |
|
5553 |
|
4875 |
err = platform_device_add_resources(pdev[i], &res, 1); |
|
|
4876 |
if (err) |
4877 |
goto exit_device_put; |
4878 |
|
4879 |
/* platform_device_add calls probe() */ |
5554 |
/* platform_device_add calls probe() */ |
4880 |
err = platform_device_add(pdev[i]); |
5555 |
err = platform_device_add(pdev[i]); |
4881 |
if (err) |
5556 |
if (err) |