^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Philip Edelbrock <phil@netroedge.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * and Mark Studebaker <mdsxyz123@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2007 - 2008 Jean Delvare <jdelvare@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Supports following chips:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * as99127f 7 3 0 3 0x31 0x12c3 yes no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * w83782d 9 3 2-4 3 0x30 0x5ca3 yes yes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * w83783s 5-6 3 2 1-2 0x40 0x5ca3 yes no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/hwmon-vid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #ifdef CONFIG_ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "lm75.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Addresses to scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 0x2e, 0x2f, I2C_CLIENT_END };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) enum chips { w83781d, w83782d, w83783s, as99127f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Insmod parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static unsigned short force_subclients[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) module_param_array(force_subclients, short, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_PARM_DESC(force_subclients,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static bool reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) module_param(reset, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static bool init = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) module_param(init, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Constants specified below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Length of ISA address segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define W83781D_EXTENT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Where are the ISA address/data registers relative to the base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define W83781D_ADDR_REG_OFFSET 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define W83781D_DATA_REG_OFFSET 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* The device registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* in nr from 0 to 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (0x554 + (((nr) - 7) * 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) (0x555 + (((nr) - 7) * 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) (0x550 + (nr) - 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* fan nr from 0 to 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define W83781D_REG_FAN_MIN(nr) (0x3b + (nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define W83781D_REG_FAN(nr) (0x28 + (nr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define W83781D_REG_BANK 0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define W83781D_REG_TEMP2_CONFIG 0x152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define W83781D_REG_TEMP3_CONFIG 0x252
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* temp nr from 1 to 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ((nr == 2) ? (0x0150) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) (0x27)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define W83781D_REG_TEMP_HYST(nr) ((nr == 3) ? (0x253) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) ((nr == 2) ? (0x153) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) (0x3A)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define W83781D_REG_TEMP_OVER(nr) ((nr == 3) ? (0x255) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ((nr == 2) ? (0x155) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (0x39)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define W83781D_REG_CONFIG 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Interrupt status (W83781D, AS99127F) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define W83781D_REG_ALARM1 0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define W83781D_REG_ALARM2 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Real-time status (W83782D, W83783S) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define W83782D_REG_ALARM1 0x459
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define W83782D_REG_ALARM2 0x45A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define W83782D_REG_ALARM3 0x45B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define W83781D_REG_BEEP_CONFIG 0x4D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define W83781D_REG_BEEP_INTS1 0x56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define W83781D_REG_BEEP_INTS2 0x57
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define W83781D_REG_BEEP_INTS3 0x453 /* not on W83781D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define W83781D_REG_VID_FANDIV 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define W83781D_REG_CHIPID 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define W83781D_REG_WCHIPID 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define W83781D_REG_CHIPMAN 0x4F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define W83781D_REG_PIN 0x4B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* 782D/783S only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define W83781D_REG_VBAT 0x5D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* PWM 782D (1-4) and 783S (1-2) only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define W83781D_REG_PWMCLK12 0x5C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define W83781D_REG_PWMCLK34 0x45C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define W83781D_REG_I2C_ADDR 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define W83781D_REG_I2C_SUBADDR 0x4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The following are undocumented in the data sheets however we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * received the information in an email from Winbond tech support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Sensor selection - not on 781d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define W83781D_REG_SCFG1 0x5D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define W83781D_REG_SCFG2 0x59
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define W83781D_DEFAULT_BETA 3435
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Conversions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define IN_TO_REG(val) clamp_val(((val) + 8) / 16, 0, 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define IN_FROM_REG(val) ((val) * 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static inline u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) FAN_TO_REG(long rpm, int div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (rpm == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rpm = clamp_val(rpm, 1, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static inline long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) FAN_FROM_REG(u8 val, int div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (val == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 1350000 / (val * div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define TEMP_TO_REG(val) clamp_val((val) / 1000, -127, 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define TEMP_FROM_REG(val) ((val) * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define BEEP_MASK_FROM_REG(val, type) ((type) == as99127f ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) (~(val)) & 0x7fff : (val) & 0xff7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define BEEP_MASK_TO_REG(val, type) ((type) == as99127f ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) (~(val)) & 0x7fff : (val) & 0xff7fff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define DIV_FROM_REG(val) (1 << (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static inline u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) DIV_TO_REG(long val, enum chips type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) val = clamp_val(val, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ((type == w83781d || type == as99127f) ? 8 : 128)) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) for (i = 0; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) val >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct w83781d_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) enum chips type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* For ISA device only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int isa_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) char valid; /* !=0 if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned long last_updated; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct i2c_client *lm75[2]; /* for secondary I2C addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* array of 2 pointers to subclients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 in[9]; /* Register value - 8 & 9 for 782D only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 in_max[9]; /* Register value - 8 & 9 for 782D only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u8 in_min[9]; /* Register value - 8 & 9 for 782D only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u8 fan[3]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u8 fan_min[3]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) s8 temp; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) s8 temp_max; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) s8 temp_max_hyst; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) u16 temp_add[2]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u16 temp_max_add[2]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u16 temp_max_hyst_add[2]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u8 fan_div[3]; /* Register encoding, shifted right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u8 vid; /* Register encoding, combined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u32 alarms; /* Register encoding, combined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 beep_mask; /* Register encoding, combined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 pwm[4]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) u8 pwm2_enable; /* Boolean */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u16 sens[3]; /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * 782D/783S only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * 1 = pentium diode; 2 = 3904 diode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * 4 = thermistor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) u8 vrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static struct w83781d_data *w83781d_data_if_isa(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int w83781d_alias_detect(struct i2c_client *client, u8 chipid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int w83781d_read_value(struct w83781d_data *data, u16 reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct w83781d_data *w83781d_update_device(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void w83781d_init_device(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* following are the sysfs callback functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define show_in_reg(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct w83781d_data *data = w83781d_update_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return sprintf(buf, "%ld\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) (long)IN_FROM_REG(data->reg[attr->index])); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) show_in_reg(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) show_in_reg(in_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) show_in_reg(in_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define store_in_reg(REG, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static ssize_t store_in_##reg(struct device *dev, struct device_attribute \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *da, const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct w83781d_data *data = dev_get_drvdata(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int nr = attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned long val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int err = kstrtoul(buf, 10, &val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) mutex_lock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) data->in_##reg[nr] = IN_TO_REG(val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) w83781d_write_value(data, W83781D_REG_IN_##REG(nr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) data->in_##reg[nr]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mutex_unlock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) store_in_reg(MIN, min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) store_in_reg(MAX, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define sysfs_in_offsets(offset) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) show_in, NULL, offset); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) show_in_min, store_in_min, offset); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) show_in_max, store_in_max, offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) sysfs_in_offsets(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sysfs_in_offsets(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) sysfs_in_offsets(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sysfs_in_offsets(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) sysfs_in_offsets(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sysfs_in_offsets(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) sysfs_in_offsets(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) sysfs_in_offsets(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) sysfs_in_offsets(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #define show_fan_reg(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct w83781d_data *data = w83781d_update_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return sprintf(buf, "%ld\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) FAN_FROM_REG(data->reg[attr->index], \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) DIV_FROM_REG(data->fan_div[attr->index]))); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) show_fan_reg(fan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) show_fan_reg(fan_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) store_fan_min(struct device *dev, struct device_attribute *da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int nr = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) data->fan_min[nr] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) w83781d_write_value(data, W83781D_REG_FAN_MIN(nr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) data->fan_min[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) show_fan_min, store_fan_min, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) show_fan_min, store_fan_min, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) show_fan_min, store_fan_min, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define show_temp_reg(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static ssize_t show_##reg(struct device *dev, struct device_attribute *da, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct w83781d_data *data = w83781d_update_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int nr = attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (nr >= 2) { /* TEMP2 and TEMP3 */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return sprintf(buf, "%d\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) } else { /* TEMP1 */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->reg)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) show_temp_reg(temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) show_temp_reg(temp_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) show_temp_reg(temp_max_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #define store_temp_reg(REG, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static ssize_t store_temp_##reg(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct device_attribute *da, const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct w83781d_data *data = dev_get_drvdata(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int nr = attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) long val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int err = kstrtol(buf, 10, &val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) mutex_lock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (nr >= 2) { /* TEMP2 and TEMP3 */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) data->temp_##reg##_add[nr-2]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) } else { /* TEMP1 */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) data->temp_##reg = TEMP_TO_REG(val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) data->temp_##reg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) mutex_unlock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) store_temp_reg(OVER, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) store_temp_reg(HYST, max_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define sysfs_temp_offsets(offset) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) show_temp, NULL, offset); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) show_temp_max, store_temp_max, offset); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) show_temp_max_hyst, store_temp_max_hyst, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) sysfs_temp_offsets(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) sysfs_temp_offsets(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) sysfs_temp_offsets(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static DEVICE_ATTR_RO(cpu0_vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) vrm_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return sprintf(buf, "%ld\n", (long) data->vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) vrm_store(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) data->vrm = clamp_val(val, 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static DEVICE_ATTR_RW(vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) alarms_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return sprintf(buf, "%u\n", data->alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static DEVICE_ATTR_RO(alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int bitnr = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* The W83781D has a single alarm bit for temp2 and temp3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static ssize_t show_temp3_alarm(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) int bitnr = (data->type == w83781d) ? 5 : 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_temp3_alarm, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static ssize_t beep_mask_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return sprintf(buf, "%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) beep_mask_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) data->beep_mask &= 0x8000; /* preserve beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) data->beep_mask |= BEEP_MASK_TO_REG(val, data->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) w83781d_write_value(data, W83781D_REG_BEEP_INTS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) data->beep_mask & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) w83781d_write_value(data, W83781D_REG_BEEP_INTS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) (data->beep_mask >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (data->type != w83781d && data->type != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) w83781d_write_value(data, W83781D_REG_BEEP_INTS3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ((data->beep_mask) >> 16) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static DEVICE_ATTR_RW(beep_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int bitnr = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) store_beep(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int bitnr = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) unsigned long bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) err = kstrtoul(buf, 10, &bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (bit & ~1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) data->beep_mask |= (1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) data->beep_mask &= ~(1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (bitnr < 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) reg |= (1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) reg &= ~(1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) w83781d_write_value(data, W83781D_REG_BEEP_INTS1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) } else if (bitnr < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) reg |= (1 << (bitnr - 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) reg &= ~(1 << (bitnr - 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) w83781d_write_value(data, W83781D_REG_BEEP_INTS2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) reg = w83781d_read_value(data, W83781D_REG_BEEP_INTS3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) reg |= (1 << (bitnr - 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) reg &= ~(1 << (bitnr - 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) w83781d_write_value(data, W83781D_REG_BEEP_INTS3, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* The W83781D has a single beep bit for temp2 and temp3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static ssize_t show_temp3_beep(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int bitnr = (data->type == w83781d) ? 5 : 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) show_beep, store_beep, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) show_beep, store_beep, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) show_beep, store_beep, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) show_beep, store_beep, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) show_beep, store_beep, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) show_beep, store_beep, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) show_beep, store_beep, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) show_beep, store_beep, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static SENSOR_DEVICE_ATTR(in8_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) show_beep, store_beep, 17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) show_beep, store_beep, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) show_beep, store_beep, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) show_beep, store_beep, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) show_beep, store_beep, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) show_beep, store_beep, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) show_temp3_beep, store_beep, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static SENSOR_DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) show_beep, store_beep, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return sprintf(buf, "%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) (long) DIV_FROM_REG(data->fan_div[attr->index]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Note: we save and restore the fan minimum here, because its value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * determined in part by the fan divisor. This follows the principle of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * least surprise; the user doesn't expect the fan minimum to change just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * because the divisor changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) store_fan_div(struct device *dev, struct device_attribute *da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) unsigned long min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int nr = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /* Save fan_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) min = FAN_FROM_REG(data->fan_min[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) data->fan_div[nr] = DIV_TO_REG(val, data->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) reg = (w83781d_read_value(data, nr == 2 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) & (nr == 0 ? 0xcf : 0x3f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) | ((data->fan_div[nr] & 0x03) << (nr == 0 ? 4 : 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) w83781d_write_value(data, nr == 2 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* w83781d and as99127f don't have extended divisor bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (data->type != w83781d && data->type != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) reg = (w83781d_read_value(data, W83781D_REG_VBAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) & ~(1 << (5 + nr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) | ((data->fan_div[nr] & 0x04) << (3 + nr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) w83781d_write_value(data, W83781D_REG_VBAT, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* Restore fan_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), data->fan_min[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) show_fan_div, store_fan_div, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) show_fan_div, store_fan_div, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) show_fan_div, store_fan_div, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) show_pwm(struct device *dev, struct device_attribute *da, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return sprintf(buf, "%d\n", (int)data->pwm[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) pwm2_enable_show(struct device *dev, struct device_attribute *da, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return sprintf(buf, "%d\n", (int)data->pwm2_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) store_pwm(struct device *dev, struct device_attribute *da, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int nr = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) data->pwm[nr] = clamp_val(val, 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) w83781d_write_value(data, W83781D_REG_PWM[nr], data->pwm[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pwm2_enable_store(struct device *dev, struct device_attribute *da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) reg = w83781d_read_value(data, W83781D_REG_PWMCLK12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) w83781d_write_value(data, W83781D_REG_PWMCLK12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) (reg & 0xf7) | (val << 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) reg = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) w83781d_write_value(data, W83781D_REG_BEEP_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) (reg & 0xef) | (!val << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) data->pwm2_enable = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* only PWM2 can be enabled/disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static DEVICE_ATTR_RW(pwm2_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) show_sensor(struct device *dev, struct device_attribute *da, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct w83781d_data *data = w83781d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return sprintf(buf, "%d\n", (int)data->sens[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) store_sensor(struct device *dev, struct device_attribute *da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int nr = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) case 1: /* PII/Celeron diode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) w83781d_write_value(data, W83781D_REG_SCFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) tmp | BIT_SCFG1[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) tmp = w83781d_read_value(data, W83781D_REG_SCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) w83781d_write_value(data, W83781D_REG_SCFG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) tmp | BIT_SCFG2[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) data->sens[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case 2: /* 3904 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) w83781d_write_value(data, W83781D_REG_SCFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) tmp | BIT_SCFG1[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) tmp = w83781d_read_value(data, W83781D_REG_SCFG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) w83781d_write_value(data, W83781D_REG_SCFG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) tmp & ~BIT_SCFG2[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) data->sens[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) case W83781D_DEFAULT_BETA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) "Sensor type %d is deprecated, please use 4 instead\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) W83781D_DEFAULT_BETA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case 4: /* thermistor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) w83781d_write_value(data, W83781D_REG_SCFG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) tmp & ~BIT_SCFG1[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) data->sens[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or 4\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) (long) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) show_sensor, store_sensor, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) show_sensor, store_sensor, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) show_sensor, store_sensor, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * Assumes that adapter is of I2C, not ISA variety.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * OTHERWISE DON'T CALL THIS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) w83781d_detect_subclients(struct i2c_client *new_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int i, val1 = 0, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int address = new_client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) unsigned short sc_addr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct i2c_adapter *adapter = new_client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct w83781d_data *data = i2c_get_clientdata(new_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) enum chips kind = data->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int num_sc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) id = i2c_adapter_id(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (force_subclients[0] == id && force_subclients[1] == address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) for (i = 2; i <= 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (force_subclients[i] < 0x48 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) force_subclients[i] > 0x4f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dev_err(&new_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) "Invalid subclient address %d; must be 0x48-0x4f\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) force_subclients[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto ERROR_SC_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) w83781d_write_value(data, W83781D_REG_I2C_SUBADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) (force_subclients[2] & 0x07) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ((force_subclients[3] & 0x07) << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) sc_addr[0] = force_subclients[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) sc_addr[0] = 0x48 + (val1 & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (kind != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) num_sc = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (force_subclients[0] == id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) force_subclients[1] == address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) sc_addr[1] = force_subclients[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) sc_addr[1] = 0x48 + ((val1 >> 4) & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (sc_addr[0] == sc_addr[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dev_err(&new_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) "Duplicate addresses 0x%x for subclients.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) sc_addr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto ERROR_SC_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) for (i = 0; i < num_sc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) data->lm75[i] = i2c_new_dummy_device(adapter, sc_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (IS_ERR(data->lm75[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) dev_err(&new_client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) "Subclient %d registration at address 0x%x failed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) i, sc_addr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) err = PTR_ERR(data->lm75[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) goto ERROR_SC_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto ERROR_SC_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Undo inits in case of errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ERROR_SC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) i2c_unregister_device(data->lm75[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) ERROR_SC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ERROR_SC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) #define IN_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) &sensor_dev_attr_in##X##_input.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) &sensor_dev_attr_in##X##_min.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) &sensor_dev_attr_in##X##_max.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) &sensor_dev_attr_in##X##_alarm.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) &sensor_dev_attr_in##X##_beep.dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) #define FAN_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) &sensor_dev_attr_fan##X##_input.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) &sensor_dev_attr_fan##X##_min.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) &sensor_dev_attr_fan##X##_div.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) &sensor_dev_attr_fan##X##_alarm.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) &sensor_dev_attr_fan##X##_beep.dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) #define TEMP_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) &sensor_dev_attr_temp##X##_input.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) &sensor_dev_attr_temp##X##_max.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) &sensor_dev_attr_temp##X##_alarm.dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) &sensor_dev_attr_temp##X##_beep.dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static struct attribute *w83781d_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) IN_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) IN_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) IN_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) IN_UNIT_ATTRS(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) IN_UNIT_ATTRS(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) IN_UNIT_ATTRS(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) FAN_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) FAN_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) FAN_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) TEMP_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) TEMP_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) &dev_attr_cpu0_vid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) &dev_attr_vrm.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) &dev_attr_alarms.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) &dev_attr_beep_mask.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) &sensor_dev_attr_beep_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static const struct attribute_group w83781d_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .attrs = w83781d_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static struct attribute *w83781d_attributes_in1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) IN_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static const struct attribute_group w83781d_group_in1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .attrs = w83781d_attributes_in1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static struct attribute *w83781d_attributes_in78[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) IN_UNIT_ATTRS(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) IN_UNIT_ATTRS(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static const struct attribute_group w83781d_group_in78 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .attrs = w83781d_attributes_in78,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static struct attribute *w83781d_attributes_temp3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) TEMP_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) static const struct attribute_group w83781d_group_temp3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .attrs = w83781d_attributes_temp3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static struct attribute *w83781d_attributes_pwm12[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) &sensor_dev_attr_pwm1.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) &sensor_dev_attr_pwm2.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) &dev_attr_pwm2_enable.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static const struct attribute_group w83781d_group_pwm12 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .attrs = w83781d_attributes_pwm12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static struct attribute *w83781d_attributes_pwm34[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) &sensor_dev_attr_pwm3.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) &sensor_dev_attr_pwm4.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static const struct attribute_group w83781d_group_pwm34 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .attrs = w83781d_attributes_pwm34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static struct attribute *w83781d_attributes_other[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) &sensor_dev_attr_temp1_type.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) &sensor_dev_attr_temp2_type.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) &sensor_dev_attr_temp3_type.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static const struct attribute_group w83781d_group_other = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .attrs = w83781d_attributes_other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) /* No clean up is done on error, it's up to the caller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) w83781d_create_files(struct device *dev, int kind, int is_isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) err = sysfs_create_group(&dev->kobj, &w83781d_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (kind != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) err = sysfs_create_group(&dev->kobj, &w83781d_group_in1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (kind != as99127f && kind != w83781d && kind != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) err = sysfs_create_group(&dev->kobj, &w83781d_group_in78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (kind != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) err = sysfs_create_group(&dev->kobj, &w83781d_group_temp3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (kind != w83781d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) err = sysfs_chmod_file(&dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) &sensor_dev_attr_temp3_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (kind != w83781d && kind != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (kind == w83782d && !is_isa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) err = sysfs_create_group(&dev->kobj, &w83781d_group_pwm34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (kind != as99127f && kind != w83781d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) err = device_create_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) &sensor_dev_attr_temp1_type.dev_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) err = device_create_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) &sensor_dev_attr_temp2_type.dev_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (kind != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) err = device_create_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) &sensor_dev_attr_temp3_type.dev_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* Return 0 if detection is successful, -ENODEV otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) w83781d_detect(struct i2c_client *client, struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) int val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) struct w83781d_data *isa = w83781d_data_if_isa();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) int address = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) const char *client_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) enum vendor { winbond, asus } vendid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * We block updates of the ISA device to minimize the risk of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * concurrent access to the same W83781D chip through different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * interfaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) mutex_lock(&isa->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG) & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) "Detection of w83781d chip failed at step 3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* Check for Winbond or Asus ID if in bank 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (!(val1 & 0x07) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ((!(val1 & 0x80) && val2 != 0xa3 && val2 != 0xc3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ((val1 & 0x80) && val2 != 0x5c && val2 != 0x12))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) "Detection of w83781d chip failed at step 4\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * If Winbond SMBus, check address at 0x48.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * Asus doesn't support, except for as99127f rev.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if ((!(val1 & 0x80) && val2 == 0xa3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ((val1 & 0x80) && val2 == 0x5c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (i2c_smbus_read_byte_data(client, W83781D_REG_I2C_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) != address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) "Detection of w83781d chip failed at step 5\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* Put it now into bank 0 and Vendor ID High Byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) (i2c_smbus_read_byte_data(client, W83781D_REG_BANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) & 0x78) | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* Get the vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (val2 == 0x5c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) vendid = winbond;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else if (val2 == 0x12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) vendid = asus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) "w83781d chip vendor is neither Winbond nor Asus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* Determine the chip type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) client_name = "w83781d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) else if (val1 == 0x30 && vendid == winbond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) client_name = "w83782d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) else if (val1 == 0x40 && vendid == winbond && address == 0x2d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) client_name = "w83783s";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) else if (val1 == 0x31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) client_name = "as99127f";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (val1 <= 0x30 && w83781d_alias_detect(client, val1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) "Device at 0x%02x appears to be the same as ISA device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) goto err_nodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) mutex_unlock(&isa->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) strlcpy(info->type, client_name, I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) err_nodev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) mutex_unlock(&isa->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) static void w83781d_remove_files(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) sysfs_remove_group(&dev->kobj, &w83781d_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) sysfs_remove_group(&dev->kobj, &w83781d_group_in1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) sysfs_remove_group(&dev->kobj, &w83781d_group_in78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) sysfs_remove_group(&dev->kobj, &w83781d_group_temp3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sysfs_remove_group(&dev->kobj, &w83781d_group_pwm12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) sysfs_remove_group(&dev->kobj, &w83781d_group_pwm34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) sysfs_remove_group(&dev->kobj, &w83781d_group_other);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static const struct i2c_device_id w83781d_ids[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static int w83781d_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct w83781d_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) data = devm_kzalloc(dev, sizeof(struct w83781d_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) data->type = i2c_match_id(w83781d_ids, client)->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* attach secondary i2c lm75-like clients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) err = w83781d_detect_subclients(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* Initialize the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) w83781d_init_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) /* Register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) err = w83781d_create_files(dev, data->type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) goto exit_remove_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) data->hwmon_dev = hwmon_device_register(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (IS_ERR(data->hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) err = PTR_ERR(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) goto exit_remove_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) exit_remove_files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) w83781d_remove_files(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) i2c_unregister_device(data->lm75[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) i2c_unregister_device(data->lm75[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) w83781d_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) struct w83781d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) hwmon_device_unregister(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) w83781d_remove_files(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) i2c_unregister_device(data->lm75[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) i2c_unregister_device(data->lm75[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) w83781d_read_value_i2c(struct w83781d_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int res, bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) struct i2c_client *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) bank = (reg >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (bank > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /* switch banks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (bank == 0 || bank > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) res = i2c_smbus_read_byte_data(client, reg & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) /* switch to subclient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) cl = data->lm75[bank - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /* convert from ISA to LM75 I2C addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) switch (reg & 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) case 0x50: /* TEMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) res = i2c_smbus_read_word_swapped(cl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case 0x52: /* CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) res = i2c_smbus_read_byte_data(cl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) case 0x53: /* HYST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) res = i2c_smbus_read_word_swapped(cl, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case 0x55: /* OVER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) res = i2c_smbus_read_word_swapped(cl, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (bank > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) int bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) struct i2c_client *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) bank = (reg >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (bank > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* switch banks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (bank == 0 || bank > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) i2c_smbus_write_byte_data(client, reg & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /* switch to subclient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) cl = data->lm75[bank - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) /* convert from ISA to LM75 I2C addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) switch (reg & 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) case 0x52: /* CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) i2c_smbus_write_byte_data(cl, 1, value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) case 0x53: /* HYST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) i2c_smbus_write_word_swapped(cl, 2, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) case 0x55: /* OVER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) i2c_smbus_write_word_swapped(cl, 3, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (bank > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) w83781d_init_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) int i, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) int type = data->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (reset && type != as99127f) { /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) * this resets registers we don't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) * documentation for on the as99127f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) * Resetting the chip has been the default for a long time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * but it causes the BIOS initializations (fan clock dividers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * thermal sensor types...) to be lost, so it is now optional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * It might even go away if nobody reports it as being useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * as I see very little reason why this would be needed at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) "If reset=1 solved a problem you were having, please report!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) /* save these registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) p = w83781d_read_value(data, W83781D_REG_PWMCLK12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * Reset all except Watchdog values and last conversion values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) * This sets fan-divs to 2, among others
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) w83781d_write_value(data, W83781D_REG_CONFIG, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * Restore the registers and disable power-on abnormal beep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * This saves FAN 1/2/3 input/output values set by BIOS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) w83781d_write_value(data, W83781D_REG_PWMCLK12, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * Disable master beep-enable (reset turns it on).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * Individual beep_mask should be reset to off but for some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * reason disabling this bit helps some people not get beeped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * Disable power-on abnormal beep, as advised by the datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) * Already done if reset=1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (init && !reset && type != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) data->vrm = vid_which_vrm();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if ((type != w83781d) && (type != as99127f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) tmp = w83781d_read_value(data, W83781D_REG_SCFG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) for (i = 1; i <= 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (!(tmp & BIT_SCFG1[i - 1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) data->sens[i - 1] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (w83781d_read_value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) (data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) data->sens[i - 1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) data->sens[i - 1] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (type == w83783s && i == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (init && type != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) /* Enable temp2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (tmp & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) "Enabling temp2, readings might not make sense\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) tmp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* Enable temp3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (type != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) tmp = w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) W83781D_REG_TEMP3_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (tmp & 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) "Enabling temp3, readings might not make sense\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) w83781d_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /* Start monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) w83781d_write_value(data, W83781D_REG_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) W83781D_REG_CONFIG) & 0xf7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* A few vars need to be filled upon startup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) data->fan_min[i] = w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) W83781D_REG_FAN_MIN(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) static struct w83781d_data *w83781d_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) dev_dbg(dev, "Starting device update\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) for (i = 0; i <= 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (data->type == w83783s && i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) continue; /* 783S has no in1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) data->in[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) w83781d_read_value(data, W83781D_REG_IN(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) data->in_min[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) w83781d_read_value(data, W83781D_REG_IN_MIN(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) data->in_max[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) w83781d_read_value(data, W83781D_REG_IN_MAX(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if ((data->type != w83782d) && (i == 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) data->fan[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) w83781d_read_value(data, W83781D_REG_FAN(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) data->fan_min[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) w83781d_read_value(data, W83781D_REG_FAN_MIN(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (data->type != w83781d && data->type != as99127f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) data->pwm[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) W83781D_REG_PWM[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /* Only W83782D on SMBus has PWM3 and PWM4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if ((data->type != w83782d || !client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) && i == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /* Only PWM2 can be disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) data->pwm2_enable = (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) W83781D_REG_PWMCLK12) & 0x08) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) data->temp_max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) w83781d_read_value(data, W83781D_REG_TEMP_OVER(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) data->temp_max_hyst =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) w83781d_read_value(data, W83781D_REG_TEMP_HYST(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) data->temp_add[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) w83781d_read_value(data, W83781D_REG_TEMP(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) data->temp_max_add[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) w83781d_read_value(data, W83781D_REG_TEMP_OVER(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) data->temp_max_hyst_add[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) w83781d_read_value(data, W83781D_REG_TEMP_HYST(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (data->type != w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) data->temp_add[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) w83781d_read_value(data, W83781D_REG_TEMP(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) data->temp_max_add[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) W83781D_REG_TEMP_OVER(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) data->temp_max_hyst_add[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) W83781D_REG_TEMP_HYST(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) i = w83781d_read_value(data, W83781D_REG_VID_FANDIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) data->vid = i & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) data->vid |= (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) W83781D_REG_CHIPID) & 0x01) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) data->fan_div[0] = (i >> 4) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) data->fan_div[1] = (i >> 6) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) data->fan_div[2] = (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) W83781D_REG_PIN) >> 6) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if ((data->type != w83781d) && (data->type != as99127f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) i = w83781d_read_value(data, W83781D_REG_VBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) data->fan_div[0] |= (i >> 3) & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) data->fan_div[1] |= (i >> 4) & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) data->fan_div[2] |= (i >> 5) & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (data->type == w83782d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) data->alarms = w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) W83782D_REG_ALARM1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) | (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) W83782D_REG_ALARM2) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) | (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) W83782D_REG_ALARM3) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) } else if (data->type == w83783s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) data->alarms = w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) W83782D_REG_ALARM1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) | (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) W83782D_REG_ALARM2) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) * No real-time status registers, fall back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) * interrupt status registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) data->alarms = w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) W83781D_REG_ALARM1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) | (w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) W83781D_REG_ALARM2) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) data->beep_mask = (i << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) w83781d_read_value(data, W83781D_REG_BEEP_INTS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if ((data->type != w83781d) && (data->type != as99127f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) data->beep_mask |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) w83781d_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) W83781D_REG_BEEP_INTS3) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static const struct i2c_device_id w83781d_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) { "w83781d", w83781d, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) { "w83782d", w83782d, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) { "w83783s", w83783s, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) { "as99127f", as99127f },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) { /* LIST END */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) MODULE_DEVICE_TABLE(i2c, w83781d_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) static struct i2c_driver w83781d_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) .name = "w83781d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .probe_new = w83781d_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .remove = w83781d_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .id_table = w83781d_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .detect = w83781d_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * ISA related code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) #ifdef CONFIG_ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* ISA device, if found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) static unsigned short isa_address = 0x290;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * I2C devices get this name attribute automatically, but for ISA devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) * we must create it by ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) name_show(struct device *dev, struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) struct w83781d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) return sprintf(buf, "%s\n", data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) static DEVICE_ATTR_RO(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) static struct w83781d_data *w83781d_data_if_isa(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return pdev ? platform_get_drvdata(pdev) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) /* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static int w83781d_alias_detect(struct i2c_client *client, u8 chipid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) struct w83781d_data *isa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (!pdev) /* No ISA chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) isa = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (w83781d_read_value(isa, W83781D_REG_I2C_ADDR) != client->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) return 0; /* Address doesn't match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (w83781d_read_value(isa, W83781D_REG_WCHIPID) != chipid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return 0; /* Chip type doesn't match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * We compare all the limit registers, the config register and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * interrupt mask registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) for (i = 0x2b; i <= 0x3d; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (w83781d_read_value(isa, i) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) i2c_smbus_read_byte_data(client, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (w83781d_read_value(isa, W83781D_REG_CONFIG) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) for (i = 0x43; i <= 0x46; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (w83781d_read_value(isa, i) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) i2c_smbus_read_byte_data(client, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) w83781d_read_value_isa(struct w83781d_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) int word_sized, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) word_sized = (((reg & 0xff00) == 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) || ((reg & 0xff00) == 0x200))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) && (((reg & 0x00ff) == 0x50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) || ((reg & 0x00ff) == 0x53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) || ((reg & 0x00ff) == 0x55));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) if (reg & 0xff00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) outb_p(W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) outb_p(reg >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) res = inb_p(data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (word_sized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) outb_p((reg & 0xff) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) res =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) (res << 8) + inb_p(data->isa_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) if (reg & 0xff00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) outb_p(W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) int word_sized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) word_sized = (((reg & 0xff00) == 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) || ((reg & 0xff00) == 0x200))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) && (((reg & 0x00ff) == 0x53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) || ((reg & 0x00ff) == 0x55));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (reg & 0xff00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) outb_p(W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) outb_p(reg >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (word_sized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) outb_p(value >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) outb_p((reg & 0xff) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) outb_p(value & 0xff, data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (reg & 0xff00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) outb_p(W83781D_REG_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) data->isa_addr + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) * The SMBus locks itself, usually, but nothing may access the Winbond between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * bank switches. ISA access must always be locked explicitly!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) * would slow down the W83781D access and should not be necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) * There are some ugly typecasts here, but the good news is - they should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) * nowhere else be necessary!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) w83781d_read_value(struct w83781d_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) res = w83781d_read_value_i2c(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) res = w83781d_read_value_isa(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) w83781d_write_value_i2c(data, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) w83781d_write_value_isa(data, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) w83781d_isa_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) int err, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) struct w83781d_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* Reserve the ISA region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) res = platform_get_resource(pdev, IORESOURCE_IO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) if (!devm_request_region(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) res->start + W83781D_ADDR_REG_OFFSET, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) "w83781d"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) data = devm_kzalloc(&pdev->dev, sizeof(struct w83781d_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) data->isa_addr = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) reg = w83781d_read_value(data, W83781D_REG_WCHIPID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) data->type = w83782d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) data->name = "w83782d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) data->type = w83781d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) data->name = "w83781d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /* Initialize the W83781D chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) w83781d_init_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) /* Register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) err = w83781d_create_files(&pdev->dev, data->type, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) goto exit_remove_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) err = device_create_file(&pdev->dev, &dev_attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) goto exit_remove_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) data->hwmon_dev = hwmon_device_register(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (IS_ERR(data->hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) err = PTR_ERR(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) goto exit_remove_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) exit_remove_files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) w83781d_remove_files(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) device_remove_file(&pdev->dev, &dev_attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) w83781d_isa_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) struct w83781d_data *data = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) hwmon_device_unregister(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) w83781d_remove_files(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) device_remove_file(&pdev->dev, &dev_attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) static struct platform_driver w83781d_isa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) .name = "w83781d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) .probe = w83781d_isa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) .remove = w83781d_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /* return 1 if a supported chip is found, 0 otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) w83781d_isa_found(unsigned short address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) int val, save, found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) * Some boards declare base+0 to base+7 as a PNP device, some base+4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * to base+7 and some base+5 to base+6. So we better request each port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * individually for the probing phase.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) for (port = address; port < address + W83781D_EXTENT; port++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) if (!request_region(port, 1, "w83781d")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) pr_debug("Failed to request port 0x%x\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) #define REALLY_SLOW_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * We need the timeouts for at least some W83781D-like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) * chips. But only if we read 'undefined' registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) val = inb_p(address + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (inb_p(address + 2) != val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) || inb_p(address + 3) != val
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) || inb_p(address + 7) != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) pr_debug("Detection failed at step %d\n", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) #undef REALLY_SLOW_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) * We should be able to change the 7 LSB of the address port. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) * MSB (busy flag) should be clear initially, set after the write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) save = inb_p(address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (save & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) pr_debug("Detection failed at step %d\n", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) val = ~save & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) outb_p(val, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) outb_p(save, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) pr_debug("Detection failed at step %d\n", 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) /* We found a device, now see if it could be a W83781D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) val = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) if (val & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) pr_debug("Detection failed at step %d\n", 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) save = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) outb_p(W83781D_REG_CHIPMAN, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) val = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if ((!(save & 0x80) && (val != 0xa3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) || ((save & 0x80) && (val != 0x5c))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) pr_debug("Detection failed at step %d\n", 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) val = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) pr_debug("Detection failed at step %d\n", 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) /* The busy flag should be clear again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) pr_debug("Detection failed at step %d\n", 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) /* Determine the chip type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) save = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) outb_p(save & 0xf8, address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) outb_p(W83781D_REG_WCHIPID, address + W83781D_ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) val = inb_p(address + W83781D_DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) if ((val & 0xfe) == 0x10 /* W83781D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) || val == 0x30) /* W83782D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) pr_info("Found a %s chip at %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) val == 0x30 ? "W83782D" : "W83781D", (int)address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) for (port--; port >= address; port--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) release_region(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) w83781d_isa_device_add(unsigned short address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct resource res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) .start = address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) .end = address + W83781D_EXTENT - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) .name = "w83781d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) pdev = platform_device_alloc("w83781d", address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) pr_err("Device allocation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) err = platform_device_add_resources(pdev, &res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) pr_err("Device resource addition failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) goto exit_device_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) err = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) pr_err("Device addition failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) goto exit_device_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) exit_device_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) w83781d_isa_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) if (w83781d_isa_found(isa_address)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) res = platform_driver_register(&w83781d_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /* Sets global pdev as a side effect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) res = w83781d_isa_device_add(isa_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) goto exit_unreg_isa_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) exit_unreg_isa_driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) platform_driver_unregister(&w83781d_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) w83781d_isa_unregister(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) platform_device_unregister(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) platform_driver_unregister(&w83781d_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) #else /* !CONFIG_ISA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) static struct w83781d_data *w83781d_data_if_isa(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) w83781d_alias_detect(struct i2c_client *client, u8 chipid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) w83781d_read_value(struct w83781d_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) res = w83781d_read_value_i2c(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) w83781d_write_value_i2c(data, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) w83781d_isa_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) w83781d_isa_unregister(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) #endif /* CONFIG_ISA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) sensors_w83781d_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * We register the ISA device first, so that we can skip the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * registration of an I2C interface to the same device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) res = w83781d_isa_register();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) res = i2c_add_driver(&w83781d_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) goto exit_unreg_isa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) exit_unreg_isa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) w83781d_isa_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) sensors_w83781d_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) w83781d_isa_unregister();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) i2c_del_driver(&w83781d_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) "Philip Edelbrock <phil@netroedge.com>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) "and Mark Studebaker <mdsxyz123@yahoo.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) MODULE_DESCRIPTION("W83781D driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) module_init(sensors_w83781d_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) module_exit(sensors_w83781d_exit);