Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'platform-drivers-x86-simatec-1' into review-hans

Tag (immutable branch) for:
v6.0-rc1 + "[PATCH v6 0/7] add support for another simatic board" series
for merging into the gpio, leds and pdx86 subsystems.

+216 -117
+2 -1
drivers/gpio/Kconfig
··· 874 874 module parameter. 875 875 876 876 config GPIO_F7188X 877 - tristate "F71869, F71869A, F71882FG, F71889F and F81866 GPIO support" 877 + tristate "Fintek and Nuvoton Super-I/O GPIO support" 878 878 help 879 879 This option enables support for GPIOs found on Fintek Super-I/O 880 880 chips F71869, F71869A, F71882FG, F71889F and F81866. 881 + As well as Nuvoton Super-I/O chip NCT6116D. 881 882 882 883 To compile this driver as a module, choose M here: the module will 883 884 be called f7188x-gpio.
+165 -110
drivers/gpio/gpio-f7188x.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * GPIO driver for Fintek Super-I/O F71869, F71869A, F71882, F71889 and F81866 3 + * GPIO driver for Fintek and Nuvoton Super-I/O chips 4 4 * 5 5 * Copyright (C) 2010-2013 LaCie 6 6 * 7 7 * Author: Simon Guinot <simon.guinot@sequanux.org> 8 8 */ 9 + 10 + #define DRVNAME "gpio-f7188x" 11 + #define pr_fmt(fmt) DRVNAME ": " fmt 9 12 10 13 #include <linux/module.h> 11 14 #include <linux/init.h> ··· 17 14 #include <linux/gpio/driver.h> 18 15 #include <linux/bitops.h> 19 16 20 - #define DRVNAME "gpio-f7188x" 21 - 22 17 /* 23 18 * Super-I/O registers 24 19 */ 25 20 #define SIO_LDSEL 0x07 /* Logical device select */ 26 21 #define SIO_DEVID 0x20 /* Device ID (2 bytes) */ 27 - #define SIO_DEVREV 0x22 /* Device revision */ 28 - #define SIO_MANID 0x23 /* Fintek ID (2 bytes) */ 29 22 30 - #define SIO_LD_GPIO 0x06 /* GPIO logical device */ 31 23 #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 32 24 #define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ 33 25 34 - #define SIO_FINTEK_ID 0x1934 /* Manufacturer ID */ 26 + /* 27 + * Fintek devices. 28 + */ 29 + #define SIO_FINTEK_DEVREV 0x22 /* Fintek Device revision */ 30 + #define SIO_FINTEK_MANID 0x23 /* Fintek ID (2 bytes) */ 31 + 32 + #define SIO_FINTEK_ID 0x1934 /* Manufacturer ID */ 33 + 35 34 #define SIO_F71869_ID 0x0814 /* F71869 chipset ID */ 36 35 #define SIO_F71869A_ID 0x1007 /* F71869A chipset ID */ 37 36 #define SIO_F71882_ID 0x0541 /* F71882 chipset ID */ 38 37 #define SIO_F71889_ID 0x0909 /* F71889 chipset ID */ 39 38 #define SIO_F71889A_ID 0x1005 /* F71889A chipset ID */ 40 39 #define SIO_F81866_ID 0x1010 /* F81866 chipset ID */ 41 - #define SIO_F81804_ID 0x1502 /* F81804 chipset ID, same for f81966 */ 40 + #define SIO_F81804_ID 0x1502 /* F81804 chipset ID, same for F81966 */ 42 41 #define SIO_F81865_ID 0x0704 /* F81865 chipset ID */ 42 + 43 + #define SIO_LD_GPIO_FINTEK 0x06 /* GPIO logical device */ 44 + 45 + /* 46 + * Nuvoton devices. 47 + */ 48 + #define SIO_NCT6116D_ID 0xD283 /* NCT6116D chipset ID */ 49 + 50 + #define SIO_LD_GPIO_NUVOTON 0x07 /* GPIO logical device */ 43 51 44 52 45 53 enum chips { ··· 62 48 f81866, 63 49 f81804, 64 50 f81865, 51 + nct6116d, 65 52 }; 66 53 67 54 static const char * const f7188x_names[] = { ··· 74 59 "f81866", 75 60 "f81804", 76 61 "f81865", 62 + "nct6116d", 77 63 }; 78 64 79 65 struct f7188x_sio { 80 66 int addr; 67 + int device; 81 68 enum chips type; 82 69 }; 83 70 ··· 127 110 { 128 111 /* Don't step on other drivers' I/O space by accident. */ 129 112 if (!request_muxed_region(base, 2, DRVNAME)) { 130 - pr_err(DRVNAME "I/O address 0x%04x already in use\n", base); 113 + pr_err("I/O address 0x%04x already in use\n", base); 131 114 return -EBUSY; 132 115 } 133 116 ··· 163 146 static int f7188x_gpio_set_config(struct gpio_chip *chip, unsigned offset, 164 147 unsigned long config); 165 148 166 - #define F7188X_GPIO_BANK(_base, _ngpio, _regbase) \ 149 + #define F7188X_GPIO_BANK(_base, _ngpio, _regbase, _label) \ 167 150 { \ 168 151 .chip = { \ 169 - .label = DRVNAME, \ 152 + .label = _label, \ 170 153 .owner = THIS_MODULE, \ 171 154 .get_direction = f7188x_gpio_get_direction, \ 172 155 .direction_input = f7188x_gpio_direction_in, \ ··· 181 164 .regbase = _regbase, \ 182 165 } 183 166 184 - #define gpio_dir(base) (base + 0) 185 - #define gpio_data_out(base) (base + 1) 186 - #define gpio_data_in(base) (base + 2) 167 + #define f7188x_gpio_dir(base) ((base) + 0) 168 + #define f7188x_gpio_data_out(base) ((base) + 1) 169 + #define f7188x_gpio_data_in(base) ((base) + 2) 187 170 /* Output mode register (0:open drain 1:push-pull). */ 188 - #define gpio_out_mode(base) (base + 3) 171 + #define f7188x_gpio_out_mode(base) ((base) + 3) 172 + 173 + #define f7188x_gpio_dir_invert(type) ((type) == nct6116d) 174 + #define f7188x_gpio_data_single(type) ((type) == nct6116d) 189 175 190 176 static struct f7188x_gpio_bank f71869_gpio_bank[] = { 191 - F7188X_GPIO_BANK(0, 6, 0xF0), 192 - F7188X_GPIO_BANK(10, 8, 0xE0), 193 - F7188X_GPIO_BANK(20, 8, 0xD0), 194 - F7188X_GPIO_BANK(30, 8, 0xC0), 195 - F7188X_GPIO_BANK(40, 8, 0xB0), 196 - F7188X_GPIO_BANK(50, 5, 0xA0), 197 - F7188X_GPIO_BANK(60, 6, 0x90), 177 + F7188X_GPIO_BANK(0, 6, 0xF0, DRVNAME "-0"), 178 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 179 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 180 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 181 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 182 + F7188X_GPIO_BANK(50, 5, 0xA0, DRVNAME "-5"), 183 + F7188X_GPIO_BANK(60, 6, 0x90, DRVNAME "-6"), 198 184 }; 199 185 200 186 static struct f7188x_gpio_bank f71869a_gpio_bank[] = { 201 - F7188X_GPIO_BANK(0, 6, 0xF0), 202 - F7188X_GPIO_BANK(10, 8, 0xE0), 203 - F7188X_GPIO_BANK(20, 8, 0xD0), 204 - F7188X_GPIO_BANK(30, 8, 0xC0), 205 - F7188X_GPIO_BANK(40, 8, 0xB0), 206 - F7188X_GPIO_BANK(50, 5, 0xA0), 207 - F7188X_GPIO_BANK(60, 8, 0x90), 208 - F7188X_GPIO_BANK(70, 8, 0x80), 187 + F7188X_GPIO_BANK(0, 6, 0xF0, DRVNAME "-0"), 188 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 189 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 190 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 191 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 192 + F7188X_GPIO_BANK(50, 5, 0xA0, DRVNAME "-5"), 193 + F7188X_GPIO_BANK(60, 8, 0x90, DRVNAME "-6"), 194 + F7188X_GPIO_BANK(70, 8, 0x80, DRVNAME "-7"), 209 195 }; 210 196 211 197 static struct f7188x_gpio_bank f71882_gpio_bank[] = { 212 - F7188X_GPIO_BANK(0, 8, 0xF0), 213 - F7188X_GPIO_BANK(10, 8, 0xE0), 214 - F7188X_GPIO_BANK(20, 8, 0xD0), 215 - F7188X_GPIO_BANK(30, 4, 0xC0), 216 - F7188X_GPIO_BANK(40, 4, 0xB0), 198 + F7188X_GPIO_BANK(0, 8, 0xF0, DRVNAME "-0"), 199 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 200 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 201 + F7188X_GPIO_BANK(30, 4, 0xC0, DRVNAME "-3"), 202 + F7188X_GPIO_BANK(40, 4, 0xB0, DRVNAME "-4"), 217 203 }; 218 204 219 205 static struct f7188x_gpio_bank f71889a_gpio_bank[] = { 220 - F7188X_GPIO_BANK(0, 7, 0xF0), 221 - F7188X_GPIO_BANK(10, 7, 0xE0), 222 - F7188X_GPIO_BANK(20, 8, 0xD0), 223 - F7188X_GPIO_BANK(30, 8, 0xC0), 224 - F7188X_GPIO_BANK(40, 8, 0xB0), 225 - F7188X_GPIO_BANK(50, 5, 0xA0), 226 - F7188X_GPIO_BANK(60, 8, 0x90), 227 - F7188X_GPIO_BANK(70, 8, 0x80), 206 + F7188X_GPIO_BANK(0, 7, 0xF0, DRVNAME "-0"), 207 + F7188X_GPIO_BANK(10, 7, 0xE0, DRVNAME "-1"), 208 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 209 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 210 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 211 + F7188X_GPIO_BANK(50, 5, 0xA0, DRVNAME "-5"), 212 + F7188X_GPIO_BANK(60, 8, 0x90, DRVNAME "-6"), 213 + F7188X_GPIO_BANK(70, 8, 0x80, DRVNAME "-7"), 228 214 }; 229 215 230 216 static struct f7188x_gpio_bank f71889_gpio_bank[] = { 231 - F7188X_GPIO_BANK(0, 7, 0xF0), 232 - F7188X_GPIO_BANK(10, 7, 0xE0), 233 - F7188X_GPIO_BANK(20, 8, 0xD0), 234 - F7188X_GPIO_BANK(30, 8, 0xC0), 235 - F7188X_GPIO_BANK(40, 8, 0xB0), 236 - F7188X_GPIO_BANK(50, 5, 0xA0), 237 - F7188X_GPIO_BANK(60, 8, 0x90), 238 - F7188X_GPIO_BANK(70, 8, 0x80), 217 + F7188X_GPIO_BANK(0, 7, 0xF0, DRVNAME "-0"), 218 + F7188X_GPIO_BANK(10, 7, 0xE0, DRVNAME "-1"), 219 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 220 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 221 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 222 + F7188X_GPIO_BANK(50, 5, 0xA0, DRVNAME "-5"), 223 + F7188X_GPIO_BANK(60, 8, 0x90, DRVNAME "-6"), 224 + F7188X_GPIO_BANK(70, 8, 0x80, DRVNAME "-7"), 239 225 }; 240 226 241 227 static struct f7188x_gpio_bank f81866_gpio_bank[] = { 242 - F7188X_GPIO_BANK(0, 8, 0xF0), 243 - F7188X_GPIO_BANK(10, 8, 0xE0), 244 - F7188X_GPIO_BANK(20, 8, 0xD0), 245 - F7188X_GPIO_BANK(30, 8, 0xC0), 246 - F7188X_GPIO_BANK(40, 8, 0xB0), 247 - F7188X_GPIO_BANK(50, 8, 0xA0), 248 - F7188X_GPIO_BANK(60, 8, 0x90), 249 - F7188X_GPIO_BANK(70, 8, 0x80), 250 - F7188X_GPIO_BANK(80, 8, 0x88), 228 + F7188X_GPIO_BANK(0, 8, 0xF0, DRVNAME "-0"), 229 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 230 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 231 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 232 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 233 + F7188X_GPIO_BANK(50, 8, 0xA0, DRVNAME "-5"), 234 + F7188X_GPIO_BANK(60, 8, 0x90, DRVNAME "-6"), 235 + F7188X_GPIO_BANK(70, 8, 0x80, DRVNAME "-7"), 236 + F7188X_GPIO_BANK(80, 8, 0x88, DRVNAME "-8"), 251 237 }; 252 238 253 239 254 240 static struct f7188x_gpio_bank f81804_gpio_bank[] = { 255 - F7188X_GPIO_BANK(0, 8, 0xF0), 256 - F7188X_GPIO_BANK(10, 8, 0xE0), 257 - F7188X_GPIO_BANK(20, 8, 0xD0), 258 - F7188X_GPIO_BANK(50, 8, 0xA0), 259 - F7188X_GPIO_BANK(60, 8, 0x90), 260 - F7188X_GPIO_BANK(70, 8, 0x80), 261 - F7188X_GPIO_BANK(90, 8, 0x98), 241 + F7188X_GPIO_BANK(0, 8, 0xF0, DRVNAME "-0"), 242 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 243 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 244 + F7188X_GPIO_BANK(50, 8, 0xA0, DRVNAME "-3"), 245 + F7188X_GPIO_BANK(60, 8, 0x90, DRVNAME "-4"), 246 + F7188X_GPIO_BANK(70, 8, 0x80, DRVNAME "-5"), 247 + F7188X_GPIO_BANK(90, 8, 0x98, DRVNAME "-6"), 262 248 }; 263 249 264 250 static struct f7188x_gpio_bank f81865_gpio_bank[] = { 265 - F7188X_GPIO_BANK(0, 8, 0xF0), 266 - F7188X_GPIO_BANK(10, 8, 0xE0), 267 - F7188X_GPIO_BANK(20, 8, 0xD0), 268 - F7188X_GPIO_BANK(30, 8, 0xC0), 269 - F7188X_GPIO_BANK(40, 8, 0xB0), 270 - F7188X_GPIO_BANK(50, 8, 0xA0), 271 - F7188X_GPIO_BANK(60, 5, 0x90), 251 + F7188X_GPIO_BANK(0, 8, 0xF0, DRVNAME "-0"), 252 + F7188X_GPIO_BANK(10, 8, 0xE0, DRVNAME "-1"), 253 + F7188X_GPIO_BANK(20, 8, 0xD0, DRVNAME "-2"), 254 + F7188X_GPIO_BANK(30, 8, 0xC0, DRVNAME "-3"), 255 + F7188X_GPIO_BANK(40, 8, 0xB0, DRVNAME "-4"), 256 + F7188X_GPIO_BANK(50, 8, 0xA0, DRVNAME "-5"), 257 + F7188X_GPIO_BANK(60, 5, 0x90, DRVNAME "-6"), 258 + }; 259 + 260 + static struct f7188x_gpio_bank nct6116d_gpio_bank[] = { 261 + F7188X_GPIO_BANK(0, 8, 0xE0, DRVNAME "-0"), 262 + F7188X_GPIO_BANK(10, 8, 0xE4, DRVNAME "-1"), 263 + F7188X_GPIO_BANK(20, 8, 0xE8, DRVNAME "-2"), 264 + F7188X_GPIO_BANK(30, 8, 0xEC, DRVNAME "-3"), 265 + F7188X_GPIO_BANK(40, 8, 0xF0, DRVNAME "-4"), 266 + F7188X_GPIO_BANK(50, 8, 0xF4, DRVNAME "-5"), 267 + F7188X_GPIO_BANK(60, 8, 0xF8, DRVNAME "-6"), 268 + F7188X_GPIO_BANK(70, 1, 0xFC, DRVNAME "-7"), 272 269 }; 273 270 274 271 static int f7188x_gpio_get_direction(struct gpio_chip *chip, unsigned offset) ··· 295 264 err = superio_enter(sio->addr); 296 265 if (err) 297 266 return err; 298 - superio_select(sio->addr, SIO_LD_GPIO); 267 + superio_select(sio->addr, sio->device); 299 268 300 - dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); 269 + dir = superio_inb(sio->addr, f7188x_gpio_dir(bank->regbase)); 301 270 302 271 superio_exit(sio->addr); 303 272 304 - if (dir & 1 << offset) 273 + if (f7188x_gpio_dir_invert(sio->type)) 274 + dir = ~dir; 275 + 276 + if (dir & BIT(offset)) 305 277 return GPIO_LINE_DIRECTION_OUT; 306 278 307 279 return GPIO_LINE_DIRECTION_IN; ··· 320 286 err = superio_enter(sio->addr); 321 287 if (err) 322 288 return err; 323 - superio_select(sio->addr, SIO_LD_GPIO); 289 + superio_select(sio->addr, sio->device); 324 290 325 - dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); 326 - dir &= ~BIT(offset); 327 - superio_outb(sio->addr, gpio_dir(bank->regbase), dir); 291 + dir = superio_inb(sio->addr, f7188x_gpio_dir(bank->regbase)); 292 + 293 + if (f7188x_gpio_dir_invert(sio->type)) 294 + dir |= BIT(offset); 295 + else 296 + dir &= ~BIT(offset); 297 + superio_outb(sio->addr, f7188x_gpio_dir(bank->regbase), dir); 328 298 329 299 superio_exit(sio->addr); 330 300 ··· 345 307 err = superio_enter(sio->addr); 346 308 if (err) 347 309 return err; 348 - superio_select(sio->addr, SIO_LD_GPIO); 310 + superio_select(sio->addr, sio->device); 349 311 350 - dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); 312 + dir = superio_inb(sio->addr, f7188x_gpio_dir(bank->regbase)); 351 313 dir = !!(dir & BIT(offset)); 352 - if (dir) 353 - data = superio_inb(sio->addr, gpio_data_out(bank->regbase)); 314 + if (f7188x_gpio_data_single(sio->type) || dir) 315 + data = superio_inb(sio->addr, f7188x_gpio_data_out(bank->regbase)); 354 316 else 355 - data = superio_inb(sio->addr, gpio_data_in(bank->regbase)); 317 + data = superio_inb(sio->addr, f7188x_gpio_data_in(bank->regbase)); 356 318 357 319 superio_exit(sio->addr); 358 320 ··· 370 332 err = superio_enter(sio->addr); 371 333 if (err) 372 334 return err; 373 - superio_select(sio->addr, SIO_LD_GPIO); 335 + superio_select(sio->addr, sio->device); 374 336 375 - data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase)); 337 + data_out = superio_inb(sio->addr, f7188x_gpio_data_out(bank->regbase)); 376 338 if (value) 377 339 data_out |= BIT(offset); 378 340 else 379 341 data_out &= ~BIT(offset); 380 - superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out); 342 + superio_outb(sio->addr, f7188x_gpio_data_out(bank->regbase), data_out); 381 343 382 - dir = superio_inb(sio->addr, gpio_dir(bank->regbase)); 383 - dir |= BIT(offset); 384 - superio_outb(sio->addr, gpio_dir(bank->regbase), dir); 344 + dir = superio_inb(sio->addr, f7188x_gpio_dir(bank->regbase)); 345 + if (f7188x_gpio_dir_invert(sio->type)) 346 + dir &= ~BIT(offset); 347 + else 348 + dir |= BIT(offset); 349 + superio_outb(sio->addr, f7188x_gpio_dir(bank->regbase), dir); 385 350 386 351 superio_exit(sio->addr); 387 352 ··· 401 360 err = superio_enter(sio->addr); 402 361 if (err) 403 362 return; 404 - superio_select(sio->addr, SIO_LD_GPIO); 363 + superio_select(sio->addr, sio->device); 405 364 406 - data_out = superio_inb(sio->addr, gpio_data_out(bank->regbase)); 365 + data_out = superio_inb(sio->addr, f7188x_gpio_data_out(bank->regbase)); 407 366 if (value) 408 367 data_out |= BIT(offset); 409 368 else 410 369 data_out &= ~BIT(offset); 411 - superio_outb(sio->addr, gpio_data_out(bank->regbase), data_out); 370 + superio_outb(sio->addr, f7188x_gpio_data_out(bank->regbase), data_out); 412 371 413 372 superio_exit(sio->addr); 414 373 } ··· 429 388 err = superio_enter(sio->addr); 430 389 if (err) 431 390 return err; 432 - superio_select(sio->addr, SIO_LD_GPIO); 391 + superio_select(sio->addr, sio->device); 433 392 434 - data = superio_inb(sio->addr, gpio_out_mode(bank->regbase)); 393 + data = superio_inb(sio->addr, f7188x_gpio_out_mode(bank->regbase)); 435 394 if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN) 436 395 data &= ~BIT(offset); 437 396 else 438 397 data |= BIT(offset); 439 - superio_outb(sio->addr, gpio_out_mode(bank->regbase), data); 398 + superio_outb(sio->addr, f7188x_gpio_out_mode(bank->regbase), data); 440 399 441 400 superio_exit(sio->addr); 442 401 return 0; ··· 490 449 data->nr_bank = ARRAY_SIZE(f81865_gpio_bank); 491 450 data->bank = f81865_gpio_bank; 492 451 break; 452 + case nct6116d: 453 + data->nr_bank = ARRAY_SIZE(nct6116d_gpio_bank); 454 + data->bank = nct6116d_gpio_bank; 455 + break; 493 456 default: 494 457 return -ENODEV; 495 458 } ··· 524 479 { 525 480 int err; 526 481 u16 devid; 482 + u16 manid; 527 483 528 484 err = superio_enter(addr); 529 485 if (err) 530 486 return err; 531 487 532 488 err = -ENODEV; 533 - devid = superio_inw(addr, SIO_MANID); 534 - if (devid != SIO_FINTEK_ID) { 535 - pr_debug(DRVNAME ": Not a Fintek device at 0x%08x\n", addr); 536 - goto err; 537 - } 538 489 490 + sio->device = SIO_LD_GPIO_FINTEK; 539 491 devid = superio_inw(addr, SIO_DEVID); 540 492 switch (devid) { 541 493 case SIO_F71869_ID: ··· 559 517 case SIO_F81865_ID: 560 518 sio->type = f81865; 561 519 break; 520 + case SIO_NCT6116D_ID: 521 + sio->device = SIO_LD_GPIO_NUVOTON; 522 + sio->type = nct6116d; 523 + break; 562 524 default: 563 - pr_info(DRVNAME ": Unsupported Fintek device 0x%04x\n", devid); 525 + pr_info("Unsupported Fintek device 0x%04x\n", devid); 564 526 goto err; 565 527 } 528 + 529 + /* double check manufacturer where possible */ 530 + if (sio->type != nct6116d) { 531 + manid = superio_inw(addr, SIO_FINTEK_MANID); 532 + if (manid != SIO_FINTEK_ID) { 533 + pr_debug("Not a Fintek device at 0x%08x\n", addr); 534 + goto err; 535 + } 536 + } 537 + 566 538 sio->addr = addr; 567 539 err = 0; 568 540 569 - pr_info(DRVNAME ": Found %s at %#x, revision %d\n", 570 - f7188x_names[sio->type], 571 - (unsigned int) addr, 572 - (int) superio_inb(addr, SIO_DEVREV)); 541 + pr_info("Found %s at %#x\n", f7188x_names[sio->type], (unsigned int)addr); 542 + if (sio->type != nct6116d) 543 + pr_info(" revision %d\n", superio_inb(addr, SIO_FINTEK_DEVREV)); 573 544 574 545 err: 575 546 superio_exit(addr); ··· 603 548 err = platform_device_add_data(f7188x_gpio_pdev, 604 549 sio, sizeof(*sio)); 605 550 if (err) { 606 - pr_err(DRVNAME "Platform data allocation failed\n"); 551 + pr_err("Platform data allocation failed\n"); 607 552 goto err; 608 553 } 609 554 610 555 err = platform_device_add(f7188x_gpio_pdev); 611 556 if (err) { 612 - pr_err(DRVNAME "Device addition failed\n"); 557 + pr_err("Device addition failed\n"); 613 558 goto err; 614 559 } 615 560
+37 -5
drivers/leds/simple/simatic-ipc-leds-gpio.c
··· 13 13 #include <linux/leds.h> 14 14 #include <linux/module.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/platform_data/x86/simatic-ipc-base.h> 16 17 17 - static struct gpiod_lookup_table simatic_ipc_led_gpio_table = { 18 + struct gpiod_lookup_table *simatic_ipc_led_gpio_table; 19 + 20 + static struct gpiod_lookup_table simatic_ipc_led_gpio_table_127e = { 18 21 .dev_id = "leds-gpio", 19 22 .table = { 20 - GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 0, GPIO_ACTIVE_LOW), 21 23 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 52, NULL, 1, GPIO_ACTIVE_LOW), 22 24 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 53, NULL, 2, GPIO_ACTIVE_LOW), 23 25 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 57, NULL, 3, GPIO_ACTIVE_LOW), 24 26 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 58, NULL, 4, GPIO_ACTIVE_LOW), 25 27 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 60, NULL, 5, GPIO_ACTIVE_LOW), 28 + GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 51, NULL, 0, GPIO_ACTIVE_LOW), 26 29 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 56, NULL, 6, GPIO_ACTIVE_LOW), 27 30 GPIO_LOOKUP_IDX("apollolake-pinctrl.0", 59, NULL, 7, GPIO_ACTIVE_HIGH), 28 31 }, 29 32 }; 30 33 34 + static struct gpiod_lookup_table simatic_ipc_led_gpio_table_227g = { 35 + .dev_id = "leds-gpio", 36 + .table = { 37 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 0, NULL, 0, GPIO_ACTIVE_LOW), 38 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 1, NULL, 1, GPIO_ACTIVE_LOW), 39 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 2, NULL, 2, GPIO_ACTIVE_LOW), 40 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 3, NULL, 3, GPIO_ACTIVE_LOW), 41 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 4, NULL, 4, GPIO_ACTIVE_LOW), 42 + GPIO_LOOKUP_IDX("gpio-f7188x-2", 5, NULL, 5, GPIO_ACTIVE_LOW), 43 + GPIO_LOOKUP_IDX("gpio-f7188x-3", 6, NULL, 6, GPIO_ACTIVE_HIGH), 44 + GPIO_LOOKUP_IDX("gpio-f7188x-3", 7, NULL, 7, GPIO_ACTIVE_HIGH), 45 + } 46 + }; 47 + 31 48 static const struct gpio_led simatic_ipc_gpio_leds[] = { 32 - { .name = "green:" LED_FUNCTION_STATUS "-3" }, 33 49 { .name = "red:" LED_FUNCTION_STATUS "-1" }, 34 50 { .name = "green:" LED_FUNCTION_STATUS "-1" }, 35 51 { .name = "red:" LED_FUNCTION_STATUS "-2" }, 36 52 { .name = "green:" LED_FUNCTION_STATUS "-2" }, 37 53 { .name = "red:" LED_FUNCTION_STATUS "-3" }, 54 + { .name = "green:" LED_FUNCTION_STATUS "-3" }, 38 55 }; 39 56 40 57 static const struct gpio_led_platform_data simatic_ipc_gpio_leds_pdata = { ··· 63 46 64 47 static int simatic_ipc_leds_gpio_remove(struct platform_device *pdev) 65 48 { 66 - gpiod_remove_lookup_table(&simatic_ipc_led_gpio_table); 49 + gpiod_remove_lookup_table(simatic_ipc_led_gpio_table); 67 50 platform_device_unregister(simatic_leds_pdev); 68 51 69 52 return 0; ··· 71 54 72 55 static int simatic_ipc_leds_gpio_probe(struct platform_device *pdev) 73 56 { 57 + const struct simatic_ipc_platform *plat = pdev->dev.platform_data; 74 58 struct gpio_desc *gpiod; 75 59 int err; 76 60 77 - gpiod_add_lookup_table(&simatic_ipc_led_gpio_table); 61 + switch (plat->devmode) { 62 + case SIMATIC_IPC_DEVICE_127E: 63 + simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_127e; 64 + break; 65 + case SIMATIC_IPC_DEVICE_227G: 66 + if (!IS_ENABLED(CONFIG_GPIO_F7188X)) 67 + return -ENODEV; 68 + request_module("gpio-f7188x"); 69 + simatic_ipc_led_gpio_table = &simatic_ipc_led_gpio_table_227g; 70 + break; 71 + default: 72 + return -ENODEV; 73 + } 74 + 75 + gpiod_add_lookup_table(simatic_ipc_led_gpio_table); 78 76 simatic_leds_pdev = platform_device_register_resndata(NULL, 79 77 "leds-gpio", PLATFORM_DEVID_NONE, NULL, 0, 80 78 &simatic_ipc_gpio_leds_pdata,
+9 -1
drivers/platform/x86/simatic-ipc.c
··· 41 41 {SIMATIC_IPC_IPC127E, SIMATIC_IPC_DEVICE_127E, SIMATIC_IPC_DEVICE_NONE}, 42 42 {SIMATIC_IPC_IPC227D, SIMATIC_IPC_DEVICE_227D, SIMATIC_IPC_DEVICE_NONE}, 43 43 {SIMATIC_IPC_IPC227E, SIMATIC_IPC_DEVICE_427E, SIMATIC_IPC_DEVICE_227E}, 44 + {SIMATIC_IPC_IPC227G, SIMATIC_IPC_DEVICE_227G, SIMATIC_IPC_DEVICE_227G}, 44 45 {SIMATIC_IPC_IPC277E, SIMATIC_IPC_DEVICE_NONE, SIMATIC_IPC_DEVICE_227E}, 45 46 {SIMATIC_IPC_IPC427D, SIMATIC_IPC_DEVICE_427E, SIMATIC_IPC_DEVICE_NONE}, 46 47 {SIMATIC_IPC_IPC427E, SIMATIC_IPC_DEVICE_427E, SIMATIC_IPC_DEVICE_427E}, 47 48 {SIMATIC_IPC_IPC477E, SIMATIC_IPC_DEVICE_NONE, SIMATIC_IPC_DEVICE_427E}, 49 + {SIMATIC_IPC_IPC427G, SIMATIC_IPC_DEVICE_227G, SIMATIC_IPC_DEVICE_227G}, 48 50 }; 49 51 50 52 static int register_platform_devices(u32 station_id) ··· 67 65 } 68 66 69 67 if (ledmode != SIMATIC_IPC_DEVICE_NONE) { 70 - if (ledmode == SIMATIC_IPC_DEVICE_127E) 68 + if (ledmode == SIMATIC_IPC_DEVICE_127E || 69 + ledmode == SIMATIC_IPC_DEVICE_227G) 71 70 pdevname = KBUILD_MODNAME "_leds_gpio"; 72 71 platform_data.devmode = ledmode; 73 72 ipc_led_platform_device = ··· 81 78 82 79 pr_debug("device=%s created\n", 83 80 ipc_led_platform_device->name); 81 + } 82 + 83 + if (wdtmode == SIMATIC_IPC_DEVICE_227G) { 84 + request_module("w83627hf_wdt"); 85 + return 0; 84 86 } 85 87 86 88 if (wdtmode != SIMATIC_IPC_DEVICE_NONE) {
+1
include/linux/platform_data/x86/simatic-ipc-base.h
··· 19 19 #define SIMATIC_IPC_DEVICE_427E 2 20 20 #define SIMATIC_IPC_DEVICE_127E 3 21 21 #define SIMATIC_IPC_DEVICE_227E 4 22 + #define SIMATIC_IPC_DEVICE_227G 5 22 23 23 24 struct simatic_ipc_platform { 24 25 u8 devmode;
+2
include/linux/platform_data/x86/simatic-ipc.h
··· 31 31 SIMATIC_IPC_IPC427E = 0x00000A01, 32 32 SIMATIC_IPC_IPC477E = 0x00000A02, 33 33 SIMATIC_IPC_IPC127E = 0x00000D01, 34 + SIMATIC_IPC_IPC227G = 0x00000F01, 35 + SIMATIC_IPC_IPC427G = 0x00001001, 34 36 }; 35 37 36 38 static inline u32 simatic_ipc_get_station_id(u8 *data, int max_len)