aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2015-03-28 11:03:10 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-04-19 09:32:36 -0400
commit3c2e35126f2821be9b6f11dd5b772c68bcef4475 (patch)
tree8f4c476369fdc7a0b79f96de3f2499e1a8a41d97
parent8e50e3c3f60c84b96956d37cbbf109b75569c6ba (diff)
hwmon: (it87) Pass SIO base address as parameter to superio functions
This will let us support more than one chip on different SIO addresses with the same driver. Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/it87.c137
1 files changed, 72 insertions, 65 deletions
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 8f28f9b04150..4840f2d8c7b1 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -80,9 +80,9 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
80 80
81static struct platform_device *it87_pdev; 81static struct platform_device *it87_pdev;
82 82
83#define REG 0x2e /* The register to read/write */ 83#define REG_2E 0x2e /* The register to read/write */
84
84#define DEV 0x07 /* Register: Logical device select */ 85#define DEV 0x07 /* Register: Logical device select */
85#define VAL 0x2f /* The value to read/write */
86#define PME 0x04 /* The device with the fan registers in it */ 86#define PME 0x04 /* The device with the fan registers in it */
87 87
88/* The device with the IT8718F/IT8720F VID value in it */ 88/* The device with the IT8718F/IT8720F VID value in it */
@@ -91,54 +91,54 @@ static struct platform_device *it87_pdev;
91#define DEVID 0x20 /* Register: Device ID */ 91#define DEVID 0x20 /* Register: Device ID */
92#define DEVREV 0x22 /* Register: Device Revision */ 92#define DEVREV 0x22 /* Register: Device Revision */
93 93
94static inline int superio_inb(int reg) 94static inline int superio_inb(int ioreg, int reg)
95{ 95{
96 outb(reg, REG); 96 outb(reg, ioreg);
97 return inb(VAL); 97 return inb(ioreg + 1);
98} 98}
99 99
100static inline void superio_outb(int reg, int val) 100static inline void superio_outb(int ioreg, int reg, int val)
101{ 101{
102 outb(reg, REG); 102 outb(reg, ioreg);
103 outb(val, VAL); 103 outb(val, ioreg + 1);
104} 104}
105 105
106static int superio_inw(int reg) 106static int superio_inw(int ioreg, int reg)
107{ 107{
108 int val; 108 int val;
109 outb(reg++, REG); 109 outb(reg++, ioreg);
110 val = inb(VAL) << 8; 110 val = inb(ioreg + 1) << 8;
111 outb(reg, REG); 111 outb(reg, ioreg);
112 val |= inb(VAL); 112 val |= inb(ioreg + 1);
113 return val; 113 return val;
114} 114}
115 115
116static inline void superio_select(int ldn) 116static inline void superio_select(int ioreg, int ldn)
117{ 117{
118 outb(DEV, REG); 118 outb(DEV, ioreg);
119 outb(ldn, VAL); 119 outb(ldn, ioreg + 1);
120} 120}
121 121
122static inline int superio_enter(void) 122static inline int superio_enter(int ioreg)
123{ 123{
124 /* 124 /*
125 * Try to reserve REG and REG + 1 for exclusive access. 125 * Try to reserve ioreg and ioreg + 1 for exclusive access.
126 */ 126 */
127 if (!request_muxed_region(REG, 2, DRVNAME)) 127 if (!request_muxed_region(ioreg, 2, DRVNAME))
128 return -EBUSY; 128 return -EBUSY;
129 129
130 outb(0x87, REG); 130 outb(0x87, ioreg);
131 outb(0x01, REG); 131 outb(0x01, ioreg);
132 outb(0x55, REG); 132 outb(0x55, ioreg);
133 outb(0x55, REG); 133 outb(0x55, ioreg);
134 return 0; 134 return 0;
135} 135}
136 136
137static inline void superio_exit(void) 137static inline void superio_exit(int ioreg)
138{ 138{
139 outb(0x02, REG); 139 outb(0x02, ioreg);
140 outb(0x02, VAL); 140 outb(0x02, ioreg + 1);
141 release_region(REG, 2); 141 release_region(ioreg, 2);
142} 142}
143 143
144/* Logical device 4 registers */ 144/* Logical device 4 registers */
@@ -1929,20 +1929,20 @@ static const struct attribute_group it87_group_label = {
1929}; 1929};
1930 1930
1931/* SuperIO detection - will change isa_address if a chip is found */ 1931/* SuperIO detection - will change isa_address if a chip is found */
1932static int __init it87_find(unsigned short *address, 1932static int __init it87_find(int sioaddr, unsigned short *address,
1933 struct it87_sio_data *sio_data) 1933 struct it87_sio_data *sio_data)
1934{ 1934{
1935 int err; 1935 int err;
1936 u16 chip_type; 1936 u16 chip_type;
1937 const char *board_vendor, *board_name; 1937 const char *board_vendor, *board_name;
1938 const struct it87_devices *config; 1938 const struct it87_devices *config;
1939 1939
1940 err = superio_enter(); 1940 err = superio_enter(sioaddr);
1941 if (err) 1941 if (err)
1942 return err; 1942 return err;
1943 1943
1944 err = -ENODEV; 1944 err = -ENODEV;
1945 chip_type = force_id ? force_id : superio_inw(DEVID); 1945 chip_type = force_id ? force_id : superio_inw(sioaddr, DEVID);
1946 1946
1947 switch (chip_type) { 1947 switch (chip_type) {
1948 case IT8705F_DEVID: 1948 case IT8705F_DEVID:
@@ -2005,20 +2005,20 @@ static int __init it87_find(unsigned short *address,
2005 goto exit; 2005 goto exit;
2006 } 2006 }
2007 2007
2008 superio_select(PME); 2008 superio_select(sioaddr, PME);
2009 if (!(superio_inb(IT87_ACT_REG) & 0x01)) { 2009 if (!(superio_inb(sioaddr, IT87_ACT_REG) & 0x01)) {
2010 pr_info("Device not activated, skipping\n"); 2010 pr_info("Device not activated, skipping\n");
2011 goto exit; 2011 goto exit;
2012 } 2012 }
2013 2013
2014 *address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1); 2014 *address = superio_inw(sioaddr, IT87_BASE_REG) & ~(IT87_EXTENT - 1);
2015 if (*address == 0) { 2015 if (*address == 0) {
2016 pr_info("Base address not set, skipping\n"); 2016 pr_info("Base address not set, skipping\n");
2017 goto exit; 2017 goto exit;
2018 } 2018 }
2019 2019
2020 err = 0; 2020 err = 0;
2021 sio_data->revision = superio_inb(DEVREV) & 0x0f; 2021 sio_data->revision = superio_inb(sioaddr, DEVREV) & 0x0f;
2022 pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type, 2022 pr_info("Found IT%04x%s chip at 0x%x, revision %d\n", chip_type,
2023 it87_devices[sio_data->type].suffix, 2023 it87_devices[sio_data->type].suffix,
2024 *address, sio_data->revision); 2024 *address, sio_data->revision);
@@ -2047,18 +2047,19 @@ static int __init it87_find(unsigned short *address,
2047 /* Read GPIO config and VID value from LDN 7 (GPIO) */ 2047 /* Read GPIO config and VID value from LDN 7 (GPIO) */
2048 if (sio_data->type == it87) { 2048 if (sio_data->type == it87) {
2049 /* The IT8705F has a different LD number for GPIO */ 2049 /* The IT8705F has a different LD number for GPIO */
2050 superio_select(5); 2050 superio_select(sioaddr, 5);
2051 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2051 sio_data->beep_pin = superio_inb(sioaddr,
2052 IT87_SIO_BEEP_PIN_REG) & 0x3f;
2052 } else if (sio_data->type == it8783) { 2053 } else if (sio_data->type == it8783) {
2053 int reg25, reg27, reg2a, reg2c, regef; 2054 int reg25, reg27, reg2a, reg2c, regef;
2054 2055
2055 superio_select(GPIO); 2056 superio_select(sioaddr, GPIO);
2056 2057
2057 reg25 = superio_inb(IT87_SIO_GPIO1_REG); 2058 reg25 = superio_inb(sioaddr, IT87_SIO_GPIO1_REG);
2058 reg27 = superio_inb(IT87_SIO_GPIO3_REG); 2059 reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
2059 reg2a = superio_inb(IT87_SIO_PINX1_REG); 2060 reg2a = superio_inb(sioaddr, IT87_SIO_PINX1_REG);
2060 reg2c = superio_inb(IT87_SIO_PINX2_REG); 2061 reg2c = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
2061 regef = superio_inb(IT87_SIO_SPI_REG); 2062 regef = superio_inb(sioaddr, IT87_SIO_SPI_REG);
2062 2063
2063 /* Check if fan3 is there or not */ 2064 /* Check if fan3 is there or not */
2064 if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2))) 2065 if ((reg27 & (1 << 0)) || !(reg2c & (1 << 2)))
@@ -2101,7 +2102,8 @@ static int __init it87_find(unsigned short *address,
2101 */ 2102 */
2102 if (!(reg2c & (1 << 1))) { 2103 if (!(reg2c & (1 << 1))) {
2103 reg2c |= (1 << 1); 2104 reg2c |= (1 << 1);
2104 superio_outb(IT87_SIO_PINX2_REG, reg2c); 2105 superio_outb(sioaddr, IT87_SIO_PINX2_REG,
2106 reg2c);
2105 pr_notice("Routing internal VCCH5V to in7.\n"); 2107 pr_notice("Routing internal VCCH5V to in7.\n");
2106 } 2108 }
2107 pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n"); 2109 pr_notice("in7 routed to internal voltage divider, with external pin disabled.\n");
@@ -2113,13 +2115,14 @@ static int __init it87_find(unsigned short *address,
2113 if (reg2c & (1 << 1)) 2115 if (reg2c & (1 << 1))
2114 sio_data->internal |= (1 << 1); 2116 sio_data->internal |= (1 << 1);
2115 2117
2116 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2118 sio_data->beep_pin = superio_inb(sioaddr,
2119 IT87_SIO_BEEP_PIN_REG) & 0x3f;
2117 } else if (sio_data->type == it8603) { 2120 } else if (sio_data->type == it8603) {
2118 int reg27, reg29; 2121 int reg27, reg29;
2119 2122
2120 superio_select(GPIO); 2123 superio_select(sioaddr, GPIO);
2121 2124
2122 reg27 = superio_inb(IT87_SIO_GPIO3_REG); 2125 reg27 = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
2123 2126
2124 /* Check if fan3 is there or not */ 2127 /* Check if fan3 is there or not */
2125 if (reg27 & (1 << 6)) 2128 if (reg27 & (1 << 6))
@@ -2128,7 +2131,7 @@ static int __init it87_find(unsigned short *address,
2128 sio_data->skip_fan |= (1 << 2); 2131 sio_data->skip_fan |= (1 << 2);
2129 2132
2130 /* Check if fan2 is there or not */ 2133 /* Check if fan2 is there or not */
2131 reg29 = superio_inb(IT87_SIO_GPIO5_REG); 2134 reg29 = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
2132 if (reg29 & (1 << 1)) 2135 if (reg29 & (1 << 1))
2133 sio_data->skip_pwm |= (1 << 1); 2136 sio_data->skip_pwm |= (1 << 1);
2134 if (reg29 & (1 << 2)) 2137 if (reg29 & (1 << 2))
@@ -2137,38 +2140,39 @@ static int __init it87_find(unsigned short *address,
2137 sio_data->skip_in |= (1 << 5); /* No VIN5 */ 2140 sio_data->skip_in |= (1 << 5); /* No VIN5 */
2138 sio_data->skip_in |= (1 << 6); /* No VIN6 */ 2141 sio_data->skip_in |= (1 << 6); /* No VIN6 */
2139 2142
2140 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2143 sio_data->beep_pin = superio_inb(sioaddr,
2144 IT87_SIO_BEEP_PIN_REG) & 0x3f;
2141 } else if (sio_data->type == it8620) { 2145 } else if (sio_data->type == it8620) {
2142 int reg; 2146 int reg;
2143 2147
2144 superio_select(GPIO); 2148 superio_select(sioaddr, GPIO);
2145 2149
2146 /* Check for pwm5 */ 2150 /* Check for pwm5 */
2147 reg = superio_inb(IT87_SIO_GPIO1_REG); 2151 reg = superio_inb(sioaddr, IT87_SIO_GPIO1_REG);
2148 if (reg & (1 << 6)) 2152 if (reg & (1 << 6))
2149 sio_data->skip_pwm |= (1 << 4); 2153 sio_data->skip_pwm |= (1 << 4);
2150 2154
2151 /* Check for fan4, fan5 */ 2155 /* Check for fan4, fan5 */
2152 reg = superio_inb(IT87_SIO_GPIO2_REG); 2156 reg = superio_inb(sioaddr, IT87_SIO_GPIO2_REG);
2153 if (!(reg & (1 << 5))) 2157 if (!(reg & (1 << 5)))
2154 sio_data->skip_fan |= (1 << 3); 2158 sio_data->skip_fan |= (1 << 3);
2155 if (!(reg & (1 << 4))) 2159 if (!(reg & (1 << 4)))
2156 sio_data->skip_fan |= (1 << 4); 2160 sio_data->skip_fan |= (1 << 4);
2157 2161
2158 /* Check for pwm3, fan3 */ 2162 /* Check for pwm3, fan3 */
2159 reg = superio_inb(IT87_SIO_GPIO3_REG); 2163 reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
2160 if (reg & (1 << 6)) 2164 if (reg & (1 << 6))
2161 sio_data->skip_pwm |= (1 << 2); 2165 sio_data->skip_pwm |= (1 << 2);
2162 if (reg & (1 << 7)) 2166 if (reg & (1 << 7))
2163 sio_data->skip_fan |= (1 << 2); 2167 sio_data->skip_fan |= (1 << 2);
2164 2168
2165 /* Check for pwm4 */ 2169 /* Check for pwm4 */
2166 reg = superio_inb(IT87_SIO_GPIO4_REG); 2170 reg = superio_inb(sioaddr, IT87_SIO_GPIO4_REG);
2167 if (!(reg & (1 << 2))) 2171 if (!(reg & (1 << 2)))
2168 sio_data->skip_pwm |= (1 << 3); 2172 sio_data->skip_pwm |= (1 << 3);
2169 2173
2170 /* Check for pwm2, fan2 */ 2174 /* Check for pwm2, fan2 */
2171 reg = superio_inb(IT87_SIO_GPIO5_REG); 2175 reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
2172 if (reg & (1 << 1)) 2176 if (reg & (1 << 1))
2173 sio_data->skip_pwm |= (1 << 1); 2177 sio_data->skip_pwm |= (1 << 1);
2174 if (reg & (1 << 2)) 2178 if (reg & (1 << 2))
@@ -2179,14 +2183,15 @@ static int __init it87_find(unsigned short *address,
2179 sio_data->skip_fan |= (1 << 5); 2183 sio_data->skip_fan |= (1 << 5);
2180 } 2184 }
2181 2185
2182 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2186 sio_data->beep_pin = superio_inb(sioaddr,
2187 IT87_SIO_BEEP_PIN_REG) & 0x3f;
2183 } else { 2188 } else {
2184 int reg; 2189 int reg;
2185 bool uart6; 2190 bool uart6;
2186 2191
2187 superio_select(GPIO); 2192 superio_select(sioaddr, GPIO);
2188 2193
2189 reg = superio_inb(IT87_SIO_GPIO3_REG); 2194 reg = superio_inb(sioaddr, IT87_SIO_GPIO3_REG);
2190 if (!sio_data->skip_vid) { 2195 if (!sio_data->skip_vid) {
2191 /* We need at least 4 VID pins */ 2196 /* We need at least 4 VID pins */
2192 if (reg & 0x0f) { 2197 if (reg & 0x0f) {
@@ -2202,7 +2207,7 @@ static int __init it87_find(unsigned short *address,
2202 sio_data->skip_fan |= (1 << 2); 2207 sio_data->skip_fan |= (1 << 2);
2203 2208
2204 /* Check if fan2 is there or not */ 2209 /* Check if fan2 is there or not */
2205 reg = superio_inb(IT87_SIO_GPIO5_REG); 2210 reg = superio_inb(sioaddr, IT87_SIO_GPIO5_REG);
2206 if (reg & (1 << 1)) 2211 if (reg & (1 << 1))
2207 sio_data->skip_pwm |= (1 << 1); 2212 sio_data->skip_pwm |= (1 << 1);
2208 if (reg & (1 << 2)) 2213 if (reg & (1 << 2))
@@ -2210,9 +2215,10 @@ static int __init it87_find(unsigned short *address,
2210 2215
2211 if ((sio_data->type == it8718 || sio_data->type == it8720) 2216 if ((sio_data->type == it8718 || sio_data->type == it8720)
2212 && !(sio_data->skip_vid)) 2217 && !(sio_data->skip_vid))
2213 sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); 2218 sio_data->vid_value = superio_inb(sioaddr,
2219 IT87_SIO_VID_REG);
2214 2220
2215 reg = superio_inb(IT87_SIO_PINX2_REG); 2221 reg = superio_inb(sioaddr, IT87_SIO_PINX2_REG);
2216 2222
2217 uart6 = sio_data->type == it8782 && (reg & (1 << 2)); 2223 uart6 = sio_data->type == it8782 && (reg & (1 << 2));
2218 2224
@@ -2232,7 +2238,7 @@ static int __init it87_find(unsigned short *address,
2232 */ 2238 */
2233 if ((sio_data->type == it8720 || uart6) && !(reg & (1 << 1))) { 2239 if ((sio_data->type == it8720 || uart6) && !(reg & (1 << 1))) {
2234 reg |= (1 << 1); 2240 reg |= (1 << 1);
2235 superio_outb(IT87_SIO_PINX2_REG, reg); 2241 superio_outb(sioaddr, IT87_SIO_PINX2_REG, reg);
2236 pr_notice("Routing internal VCCH to in7\n"); 2242 pr_notice("Routing internal VCCH to in7\n");
2237 } 2243 }
2238 if (reg & (1 << 0)) 2244 if (reg & (1 << 0))
@@ -2254,7 +2260,8 @@ static int __init it87_find(unsigned short *address,
2254 sio_data->skip_temp |= (1 << 2); 2260 sio_data->skip_temp |= (1 << 2);
2255 } 2261 }
2256 2262
2257 sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f; 2263 sio_data->beep_pin = superio_inb(sioaddr,
2264 IT87_SIO_BEEP_PIN_REG) & 0x3f;
2258 } 2265 }
2259 if (sio_data->beep_pin) 2266 if (sio_data->beep_pin)
2260 pr_info("Beeping is supported\n"); 2267 pr_info("Beeping is supported\n");
@@ -2279,7 +2286,7 @@ static int __init it87_find(unsigned short *address,
2279 } 2286 }
2280 2287
2281exit: 2288exit:
2282 superio_exit(); 2289 superio_exit(sioaddr);
2283 return err; 2290 return err;
2284} 2291}
2285 2292
@@ -2939,7 +2946,7 @@ static int __init sm_it87_init(void)
2939 struct it87_sio_data sio_data; 2946 struct it87_sio_data sio_data;
2940 2947
2941 memset(&sio_data, 0, sizeof(struct it87_sio_data)); 2948 memset(&sio_data, 0, sizeof(struct it87_sio_data));
2942 err = it87_find(&isa_address, &sio_data); 2949 err = it87_find(REG_2E, &isa_address, &sio_data);
2943 if (err) 2950 if (err)
2944 return err; 2951 return err;
2945 err = platform_driver_register(&it87_driver); 2952 err = platform_driver_register(&it87_driver);