Lines Matching +full:channel +full:- +full:3
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * nct7904.c - driver for Nuvoton NCT7904D.
43 #define VSEN_MAX 21 /* VSEN1..14, 3VDD, VBAT, V3VSB,
92 #define FANCTL1_FMR_REG 0x00 /* Bank 3; 1 reg per channel */
93 #define FANCTL1_OUT_REG 0x10 /* Bank 3; 1 reg per channel */
110 /*The timeout range is 1-255 minutes*/
141 u8 vsen_alarm[3];
149 mutex_lock(&data->bank_lock); in nct7904_bank_lock()
150 if (data->bank_sel == bank) in nct7904_bank_lock()
152 ret = i2c_smbus_write_byte_data(data->client, BANK_SEL_REG, bank); in nct7904_bank_lock()
154 data->bank_sel = bank; in nct7904_bank_lock()
156 data->bank_sel = -1; in nct7904_bank_lock()
162 mutex_unlock(&data->bank_lock); in nct7904_bank_release()
165 /* Read 1-byte register. Returns unsigned reg or -ERRNO on error. */
169 struct i2c_client *client = data->client; in nct7904_read_reg()
181 * Read 2-byte register. Returns register in big-endian format or
182 * -ERRNO on error.
187 struct i2c_client *client = data->client; in nct7904_read_reg16()
205 /* Write 1-byte register. Returns 0 or -ERRNO on error. */
209 struct i2c_client *client = data->client; in nct7904_write_reg()
220 static int nct7904_read_fan(struct device *dev, u32 attr, int channel, in nct7904_read_fan() argument
230 FANIN1_HV_REG + channel * 2); in nct7904_read_fan()
233 cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); in nct7904_read_fan()
242 FANIN1_HV_HL_REG + channel * 2); in nct7904_read_fan()
245 cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); in nct7904_read_fan()
254 SMI_STS5_REG + (channel >> 3)); in nct7904_read_fan()
257 if (!data->fan_alarm[channel >> 3]) in nct7904_read_fan()
258 data->fan_alarm[channel >> 3] = ret & 0xff; in nct7904_read_fan()
261 data->fan_alarm[channel >> 3] |= (ret & 0xff); in nct7904_read_fan()
262 *val = (data->fan_alarm[channel >> 3] >> (channel & 0x07)) & 1; in nct7904_read_fan()
265 data->fan_alarm[channel >> 3] ^= 1 << (channel & 0x07); in nct7904_read_fan()
268 return -EOPNOTSUPP; in nct7904_read_fan()
272 static umode_t nct7904_fan_is_visible(const void *_data, u32 attr, int channel) in nct7904_fan_is_visible() argument
279 if (data->fanin_mask & (1 << channel)) in nct7904_fan_is_visible()
283 if (data->fanin_mask & (1 << channel)) in nct7904_fan_is_visible()
295 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
299 static int nct7904_read_in(struct device *dev, u32 attr, int channel, in nct7904_read_in() argument
305 index = nct7904_chan_to_index[channel]; in nct7904_read_in()
346 SMI_STS1_REG + (index >> 3)); in nct7904_read_in()
349 if (!data->vsen_alarm[index >> 3]) in nct7904_read_in()
350 data->vsen_alarm[index >> 3] = ret & 0xff; in nct7904_read_in()
353 data->vsen_alarm[index >> 3] |= (ret & 0xff); in nct7904_read_in()
354 *val = (data->vsen_alarm[index >> 3] >> (index & 0x07)) & 1; in nct7904_read_in()
357 data->vsen_alarm[index >> 3] ^= 1 << (index & 0x07); in nct7904_read_in()
360 return -EOPNOTSUPP; in nct7904_read_in()
364 static umode_t nct7904_in_is_visible(const void *_data, u32 attr, int channel) in nct7904_in_is_visible() argument
367 int index = nct7904_chan_to_index[channel]; in nct7904_in_is_visible()
372 if (channel > 0 && (data->vsen_mask & BIT(index))) in nct7904_in_is_visible()
377 if (channel > 0 && (data->vsen_mask & BIT(index))) in nct7904_in_is_visible()
387 static int nct7904_read_temp(struct device *dev, u32 attr, int channel, in nct7904_read_temp() argument
397 if (channel == 4) in nct7904_read_temp()
399 else if (channel < 5) in nct7904_read_temp()
401 TEMP_CH1_HV_REG + channel * 4); in nct7904_read_temp()
404 T_CPU1_HV_REG + (channel - 5) in nct7904_read_temp()
412 if (channel == 4) { in nct7904_read_temp()
418 } else if (channel < 4) { in nct7904_read_temp()
423 *val = (ret >> (((channel * 2) + 1) & 0x07)) & 1; in nct7904_read_temp()
425 if ((channel - 5) < 4) { in nct7904_read_temp()
428 ((channel - 5) >> 3)); in nct7904_read_temp()
431 *val = (ret >> ((channel - 5) & 0x07)) & 1; in nct7904_read_temp()
435 ((channel - 5) >> 3)); in nct7904_read_temp()
438 *val = (ret >> (((channel - 5) & 0x07) - 4)) in nct7904_read_temp()
444 if (channel < 5) { in nct7904_read_temp()
445 if ((data->tcpu_mask >> channel) & 0x01) { in nct7904_read_temp()
446 if ((data->temp_mode >> channel) & 0x01) in nct7904_read_temp()
447 *val = 3; /* TD */ in nct7904_read_temp()
454 if ((data->has_dts >> (channel - 5)) & 0x01) { in nct7904_read_temp()
455 if (data->enable_dts & ENABLE_TSI) in nct7904_read_temp()
485 return -EOPNOTSUPP; in nct7904_read_temp()
488 if (channel == 4) in nct7904_read_temp()
490 else if (channel < 5) in nct7904_read_temp()
492 reg2 + channel * 8); in nct7904_read_temp()
495 reg3 + (channel - 5) * 4); in nct7904_read_temp()
504 static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel) in nct7904_temp_is_visible() argument
512 if (channel < 5) { in nct7904_temp_is_visible()
513 if (data->tcpu_mask & BIT(channel)) in nct7904_temp_is_visible()
516 if (data->has_dts & BIT(channel - 5)) in nct7904_temp_is_visible()
524 if (channel < 5) { in nct7904_temp_is_visible()
525 if (data->tcpu_mask & BIT(channel)) in nct7904_temp_is_visible()
528 if (data->has_dts & BIT(channel - 5)) in nct7904_temp_is_visible()
539 static int nct7904_read_pwm(struct device *dev, u32 attr, int channel, in nct7904_read_pwm() argument
547 ret = nct7904_read_reg(data, BANK_3, FANCTL1_OUT_REG + channel); in nct7904_read_pwm()
553 ret = nct7904_read_reg(data, BANK_3, FANCTL1_FMR_REG + channel); in nct7904_read_pwm()
560 return -EOPNOTSUPP; in nct7904_read_pwm()
564 static int nct7904_write_temp(struct device *dev, u32 attr, int channel, in nct7904_write_temp() argument
571 val = clamp_val(val / 1000, -128, 127); in nct7904_write_temp()
595 return -EOPNOTSUPP; in nct7904_write_temp()
597 if (channel == 4) in nct7904_write_temp()
599 else if (channel < 5) in nct7904_write_temp()
601 reg2 + channel * 8, val); in nct7904_write_temp()
604 reg3 + (channel - 5) * 4, val); in nct7904_write_temp()
609 static int nct7904_write_fan(struct device *dev, u32 attr, int channel, in nct7904_write_fan() argument
619 return -EINVAL; in nct7904_write_fan()
624 FANIN1_HV_HL_REG + channel * 2, tmp); in nct7904_write_fan()
629 FANIN1_LV_HL_REG + channel * 2, tmp); in nct7904_write_fan()
632 return -EOPNOTSUPP; in nct7904_write_fan()
636 static int nct7904_write_in(struct device *dev, u32 attr, int channel, in nct7904_write_in() argument
642 index = nct7904_chan_to_index[channel]; in nct7904_write_in()
667 tmp = (val >> 3) & 0xff; in nct7904_write_in()
686 tmp = (val >> 3) & 0xff; in nct7904_write_in()
691 return -EOPNOTSUPP; in nct7904_write_in()
695 static int nct7904_write_pwm(struct device *dev, u32 attr, int channel, in nct7904_write_pwm() argument
704 return -EINVAL; in nct7904_write_pwm()
705 ret = nct7904_write_reg(data, BANK_3, FANCTL1_OUT_REG + channel, in nct7904_write_pwm()
710 (val == 2 && !data->fan_mode[channel])) in nct7904_write_pwm()
711 return -EINVAL; in nct7904_write_pwm()
712 ret = nct7904_write_reg(data, BANK_3, FANCTL1_FMR_REG + channel, in nct7904_write_pwm()
713 val == 2 ? data->fan_mode[channel] : 0); in nct7904_write_pwm()
716 return -EOPNOTSUPP; in nct7904_write_pwm()
720 static umode_t nct7904_pwm_is_visible(const void *_data, u32 attr, int channel) in nct7904_pwm_is_visible() argument
732 u32 attr, int channel, long *val) in nct7904_read() argument
736 return nct7904_read_in(dev, attr, channel, val); in nct7904_read()
738 return nct7904_read_fan(dev, attr, channel, val); in nct7904_read()
740 return nct7904_read_pwm(dev, attr, channel, val); in nct7904_read()
742 return nct7904_read_temp(dev, attr, channel, val); in nct7904_read()
744 return -EOPNOTSUPP; in nct7904_read()
749 u32 attr, int channel, long val) in nct7904_write() argument
753 return nct7904_write_in(dev, attr, channel, val); in nct7904_write()
755 return nct7904_write_fan(dev, attr, channel, val); in nct7904_write()
757 return nct7904_write_pwm(dev, attr, channel, val); in nct7904_write()
759 return nct7904_write_temp(dev, attr, channel, val); in nct7904_write()
761 return -EOPNOTSUPP; in nct7904_write()
767 u32 attr, int channel) in nct7904_is_visible() argument
771 return nct7904_in_is_visible(data, attr, channel); in nct7904_is_visible()
773 return nct7904_fan_is_visible(data, attr, channel); in nct7904_is_visible()
775 return nct7904_pwm_is_visible(data, attr, channel); in nct7904_is_visible()
777 return nct7904_temp_is_visible(data, attr, channel); in nct7904_is_visible()
783 /* Return 0 if detection is successful, -ENODEV otherwise */
787 struct i2c_adapter *adapter = client->adapter; in nct7904_detect()
792 return -ENODEV; in nct7904_detect()
799 return -ENODEV; in nct7904_detect()
801 strscpy(info->type, "nct7904", I2C_NAME_SIZE); in nct7904_detect()
947 * Its minimum unit is minutes. And wdt->timeout needs in nct7904_wdt_set_timeout()
949 * to be: wdt->timeout = timeout / 60 * 60. in nct7904_wdt_set_timeout()
952 * So, wdt->timeout must then be set to 60 seconds. in nct7904_wdt_set_timeout()
954 wdt->timeout = timeout / 60 * 60; in nct7904_wdt_set_timeout()
957 wdt->timeout / 60); in nct7904_wdt_set_timeout()
977 ret = nct7904_write_reg(data, BANK_0, WDT_TIMER_REG, wdt->timeout / 60); in nct7904_wdt_ping()
1016 struct device *dev = &client->dev; in nct7904_probe()
1023 return -ENOMEM; in nct7904_probe()
1025 data->client = client; in nct7904_probe()
1026 mutex_init(&data->bank_lock); in nct7904_probe()
1027 data->bank_sel = -1; in nct7904_probe()
1034 data->fanin_mask = (ret >> 8) | ((ret & 0xff) << 8); in nct7904_probe()
1050 data->vsen_mask = mask; in nct7904_probe()
1058 data->tcpu_mask |= 1; /* TR1 */ in nct7904_probe()
1060 data->tcpu_mask |= 2; /* TR2 */ in nct7904_probe()
1062 data->tcpu_mask |= 4; /* TR3 */ in nct7904_probe()
1064 data->tcpu_mask |= 8; /* TR4 */ in nct7904_probe()
1071 data->tcpu_mask |= 0x10; in nct7904_probe()
1073 /* Multi-Function detecting for Volt and TR/TD */ in nct7904_probe()
1078 data->temp_mode = 0; in nct7904_probe()
1083 data->tcpu_mask &= ~bit; in nct7904_probe()
1085 data->temp_mode |= bit; in nct7904_probe()
1086 data->vsen_mask &= ~(0x06 << (i * 2)); in nct7904_probe()
1088 data->vsen_mask &= ~(0x02 << (i * 2)); in nct7904_probe()
1091 data->tcpu_mask &= ~bit; in nct7904_probe()
1092 data->vsen_mask &= ~(0x06 << (i * 2)); in nct7904_probe()
1101 data->enable_dts = 1; /* Enable DTS & PECI */ in nct7904_probe()
1107 data->enable_dts = 0x3; /* Enable DTS & TSI */ in nct7904_probe()
1111 if (data->enable_dts) { in nct7904_probe()
1115 data->has_dts = ret & 0xF; in nct7904_probe()
1116 if (data->enable_dts & ENABLE_TSI) { in nct7904_probe()
1120 data->has_dts |= (ret & 0xF) << 4; in nct7904_probe()
1128 data->fan_mode[i] = ret; in nct7904_probe()
1139 devm_hwmon_device_register_with_info(dev, client->name, data, in nct7904_probe()
1146 data->wdt.ops = &nct7904_wdt_ops; in nct7904_probe()
1147 data->wdt.info = &nct7904_wdt_info; in nct7904_probe()
1149 data->wdt.timeout = WATCHDOG_TIMEOUT * 60; /* Set default timeout */ in nct7904_probe()
1150 data->wdt.min_timeout = MIN_TIMEOUT; in nct7904_probe()
1151 data->wdt.max_timeout = MAX_TIMEOUT; in nct7904_probe()
1152 data->wdt.parent = &client->dev; in nct7904_probe()
1154 watchdog_init_timeout(&data->wdt, timeout * 60, &client->dev); in nct7904_probe()
1155 watchdog_set_nowayout(&data->wdt, nowayout); in nct7904_probe()
1156 watchdog_set_drvdata(&data->wdt, data); in nct7904_probe()
1158 watchdog_stop_on_unregister(&data->wdt); in nct7904_probe()
1160 return devm_watchdog_register_device(dev, &data->wdt); in nct7904_probe()