1 /* 2 * GPIO driver for the SMSC SCH311x Super-I/O chips 3 * 4 * Copyright (C) 2013 Bruno Randolf <br1@einfach.org> 5 * 6 * SuperIO functions and chip detection: 7 * (c) Copyright 2008 Wim Van Sebroeck <wim@iguana.be>. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/kernel.h> 17 #include <linux/init.h> 18 #include <linux/platform_device.h> 19 #include <linux/gpio.h> 20 #include <linux/bitops.h> 21 #include <linux/io.h> 22 23 #define DRV_NAME "gpio-sch311x" 24 25 #define SCH311X_GPIO_CONF_OUT 0x00 26 #define SCH311X_GPIO_CONF_IN 0x01 27 #define SCH311X_GPIO_CONF_INVERT 0x02 28 #define SCH311X_GPIO_CONF_OPEN_DRAIN 0x80 29 30 #define SIO_CONFIG_KEY_ENTER 0x55 31 #define SIO_CONFIG_KEY_EXIT 0xaa 32 33 #define GP1 0x4b 34 35 static int sch311x_ioports[] = { 0x2e, 0x4e, 0x162e, 0x164e }; 36 37 static struct platform_device *sch311x_gpio_pdev; 38 39 struct sch311x_pdev_data { /* platform device data */ 40 unsigned short runtime_reg; /* runtime register base address */ 41 }; 42 43 struct sch311x_gpio_block { /* one GPIO block runtime data */ 44 struct gpio_chip chip; 45 unsigned short data_reg; /* from definition below */ 46 unsigned short *config_regs; /* pointer to definition below */ 47 unsigned short runtime_reg; /* runtime register */ 48 spinlock_t lock; /* lock for this GPIO block */ 49 }; 50 51 struct sch311x_gpio_priv { /* driver private data */ 52 struct sch311x_gpio_block blocks[6]; 53 }; 54 55 struct sch311x_gpio_block_def { /* register address definitions */ 56 unsigned short data_reg; 57 unsigned short config_regs[8]; 58 unsigned short base; 59 }; 60 61 /* Note: some GPIOs are not available, these are marked with 0x00 */ 62 63 static struct sch311x_gpio_block_def sch311x_gpio_blocks[] = { 64 { 65 .data_reg = 0x4b, /* GP1 */ 66 .config_regs = {0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2b}, 67 .base = 10, 68 }, 69 { 70 .data_reg = 0x4c, /* GP2 */ 71 .config_regs = {0x00, 0x2c, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x32}, 72 .base = 20, 73 }, 74 { 75 .data_reg = 0x4d, /* GP3 */ 76 .config_regs = {0x33, 0x34, 0x35, 0x36, 0x37, 0x00, 0x39, 0x3a}, 77 .base = 30, 78 }, 79 { 80 .data_reg = 0x4e, /* GP4 */ 81 .config_regs = {0x3b, 0x00, 0x3d, 0x00, 0x6e, 0x6f, 0x72, 0x73}, 82 .base = 40, 83 }, 84 { 85 .data_reg = 0x4f, /* GP5 */ 86 .config_regs = {0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}, 87 .base = 50, 88 }, 89 { 90 .data_reg = 0x50, /* GP6 */ 91 .config_regs = {0x47, 0x48, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59}, 92 .base = 60, 93 }, 94 }; 95 96 static inline struct sch311x_gpio_block * 97 to_sch311x_gpio_block(struct gpio_chip *chip) 98 { 99 return container_of(chip, struct sch311x_gpio_block, chip); 100 } 101 102 103 /* 104 * Super-IO functions 105 */ 106 107 static inline int sch311x_sio_enter(int sio_config_port) 108 { 109 /* Don't step on other drivers' I/O space by accident. */ 110 if (!request_muxed_region(sio_config_port, 2, DRV_NAME)) { 111 pr_err(DRV_NAME "I/O address 0x%04x already in use\n", 112 sio_config_port); 113 return -EBUSY; 114 } 115 116 outb(SIO_CONFIG_KEY_ENTER, sio_config_port); 117 return 0; 118 } 119 120 static inline void sch311x_sio_exit(int sio_config_port) 121 { 122 outb(SIO_CONFIG_KEY_EXIT, sio_config_port); 123 release_region(sio_config_port, 2); 124 } 125 126 static inline int sch311x_sio_inb(int sio_config_port, int reg) 127 { 128 outb(reg, sio_config_port); 129 return inb(sio_config_port + 1); 130 } 131 132 static inline void sch311x_sio_outb(int sio_config_port, int reg, int val) 133 { 134 outb(reg, sio_config_port); 135 outb(val, sio_config_port + 1); 136 } 137 138 139 /* 140 * GPIO functions 141 */ 142 143 static int sch311x_gpio_request(struct gpio_chip *chip, unsigned offset) 144 { 145 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 146 147 if (block->config_regs[offset] == 0) /* GPIO is not available */ 148 return -ENODEV; 149 150 if (!request_region(block->runtime_reg + block->config_regs[offset], 151 1, DRV_NAME)) { 152 dev_err(chip->dev, "Failed to request region 0x%04x.\n", 153 block->runtime_reg + block->config_regs[offset]); 154 return -EBUSY; 155 } 156 return 0; 157 } 158 159 static void sch311x_gpio_free(struct gpio_chip *chip, unsigned offset) 160 { 161 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 162 163 if (block->config_regs[offset] == 0) /* GPIO is not available */ 164 return; 165 166 release_region(block->runtime_reg + block->config_regs[offset], 1); 167 } 168 169 static int sch311x_gpio_get(struct gpio_chip *chip, unsigned offset) 170 { 171 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 172 unsigned char data; 173 174 spin_lock(&block->lock); 175 data = inb(block->runtime_reg + block->data_reg); 176 spin_unlock(&block->lock); 177 178 return !!(data & BIT(offset)); 179 } 180 181 static void __sch311x_gpio_set(struct sch311x_gpio_block *block, 182 unsigned offset, int value) 183 { 184 unsigned char data = inb(block->runtime_reg + block->data_reg); 185 if (value) 186 data |= BIT(offset); 187 else 188 data &= ~BIT(offset); 189 outb(data, block->runtime_reg + block->data_reg); 190 } 191 192 static void sch311x_gpio_set(struct gpio_chip *chip, unsigned offset, 193 int value) 194 { 195 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 196 197 spin_lock(&block->lock); 198 __sch311x_gpio_set(block, offset, value); 199 spin_unlock(&block->lock); 200 } 201 202 static int sch311x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) 203 { 204 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 205 206 spin_lock(&block->lock); 207 outb(SCH311X_GPIO_CONF_IN, block->runtime_reg + 208 block->config_regs[offset]); 209 spin_unlock(&block->lock); 210 211 return 0; 212 } 213 214 static int sch311x_gpio_direction_out(struct gpio_chip *chip, unsigned offset, 215 int value) 216 { 217 struct sch311x_gpio_block *block = to_sch311x_gpio_block(chip); 218 219 spin_lock(&block->lock); 220 221 outb(SCH311X_GPIO_CONF_OUT, block->runtime_reg + 222 block->config_regs[offset]); 223 224 __sch311x_gpio_set(block, offset, value); 225 226 spin_unlock(&block->lock); 227 return 0; 228 } 229 230 static int sch311x_gpio_probe(struct platform_device *pdev) 231 { 232 struct sch311x_pdev_data *pdata = pdev->dev.platform_data; 233 struct sch311x_gpio_priv *priv; 234 struct sch311x_gpio_block *block; 235 int err, i; 236 237 /* we can register all GPIO data registers at once */ 238 if (!request_region(pdata->runtime_reg + GP1, 6, DRV_NAME)) { 239 dev_err(&pdev->dev, "Failed to request region 0x%04x-0x%04x.\n", 240 pdata->runtime_reg + GP1, pdata->runtime_reg + GP1 + 5); 241 return -EBUSY; 242 } 243 244 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 245 if (!priv) 246 return -ENOMEM; 247 248 platform_set_drvdata(pdev, priv); 249 250 for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) { 251 block = &priv->blocks[i]; 252 253 spin_lock_init(&block->lock); 254 255 block->chip.label = DRV_NAME; 256 block->chip.owner = THIS_MODULE; 257 block->chip.request = sch311x_gpio_request; 258 block->chip.free = sch311x_gpio_free; 259 block->chip.direction_input = sch311x_gpio_direction_in; 260 block->chip.direction_output = sch311x_gpio_direction_out; 261 block->chip.get = sch311x_gpio_get; 262 block->chip.set = sch311x_gpio_set; 263 block->chip.ngpio = 8; 264 block->chip.dev = &pdev->dev; 265 block->chip.base = sch311x_gpio_blocks[i].base; 266 block->config_regs = sch311x_gpio_blocks[i].config_regs; 267 block->data_reg = sch311x_gpio_blocks[i].data_reg; 268 block->runtime_reg = pdata->runtime_reg; 269 270 err = gpiochip_add(&block->chip); 271 if (err < 0) { 272 dev_err(&pdev->dev, 273 "Could not register gpiochip, %d\n", err); 274 goto exit_err; 275 } 276 dev_info(&pdev->dev, 277 "SMSC SCH311x GPIO block %d registered.\n", i); 278 } 279 280 return 0; 281 282 exit_err: 283 release_region(pdata->runtime_reg + GP1, 6); 284 /* release already registered chips */ 285 for (--i; i >= 0; i--) 286 gpiochip_remove(&priv->blocks[i].chip); 287 return err; 288 } 289 290 static int sch311x_gpio_remove(struct platform_device *pdev) 291 { 292 struct sch311x_pdev_data *pdata = pdev->dev.platform_data; 293 struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev); 294 int i; 295 296 release_region(pdata->runtime_reg + GP1, 6); 297 298 for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) { 299 gpiochip_remove(&priv->blocks[i].chip); 300 dev_info(&pdev->dev, 301 "SMSC SCH311x GPIO block %d unregistered.\n", i); 302 } 303 return 0; 304 } 305 306 static struct platform_driver sch311x_gpio_driver = { 307 .driver.name = DRV_NAME, 308 .driver.owner = THIS_MODULE, 309 .probe = sch311x_gpio_probe, 310 .remove = sch311x_gpio_remove, 311 }; 312 313 314 /* 315 * Init & exit routines 316 */ 317 318 static int __init sch311x_detect(int sio_config_port, unsigned short *addr) 319 { 320 int err = 0, reg; 321 unsigned short base_addr; 322 unsigned char dev_id; 323 324 err = sch311x_sio_enter(sio_config_port); 325 if (err) 326 return err; 327 328 /* Check device ID. */ 329 reg = sch311x_sio_inb(sio_config_port, 0x20); 330 switch (reg) { 331 case 0x7c: /* SCH3112 */ 332 dev_id = 2; 333 break; 334 case 0x7d: /* SCH3114 */ 335 dev_id = 4; 336 break; 337 case 0x7f: /* SCH3116 */ 338 dev_id = 6; 339 break; 340 default: 341 err = -ENODEV; 342 goto exit; 343 } 344 345 /* Select logical device A (runtime registers) */ 346 sch311x_sio_outb(sio_config_port, 0x07, 0x0a); 347 348 /* Check if Logical Device Register is currently active */ 349 if ((sch311x_sio_inb(sio_config_port, 0x30) & 0x01) == 0) 350 pr_info("Seems that LDN 0x0a is not active...\n"); 351 352 /* Get the base address of the runtime registers */ 353 base_addr = (sch311x_sio_inb(sio_config_port, 0x60) << 8) | 354 sch311x_sio_inb(sio_config_port, 0x61); 355 if (!base_addr) { 356 pr_err("Base address not set\n"); 357 err = -ENODEV; 358 goto exit; 359 } 360 *addr = base_addr; 361 362 pr_info("Found an SMSC SCH311%d chip at 0x%04x\n", dev_id, base_addr); 363 364 exit: 365 sch311x_sio_exit(sio_config_port); 366 return err; 367 } 368 369 static int __init sch311x_gpio_pdev_add(const unsigned short addr) 370 { 371 struct sch311x_pdev_data pdata; 372 int err; 373 374 pdata.runtime_reg = addr; 375 376 sch311x_gpio_pdev = platform_device_alloc(DRV_NAME, -1); 377 if (!sch311x_gpio_pdev) 378 return -ENOMEM; 379 380 err = platform_device_add_data(sch311x_gpio_pdev, 381 &pdata, sizeof(pdata)); 382 if (err) { 383 pr_err(DRV_NAME "Platform data allocation failed\n"); 384 goto err; 385 } 386 387 err = platform_device_add(sch311x_gpio_pdev); 388 if (err) { 389 pr_err(DRV_NAME "Device addition failed\n"); 390 goto err; 391 } 392 return 0; 393 394 err: 395 platform_device_put(sch311x_gpio_pdev); 396 return err; 397 } 398 399 static int __init sch311x_gpio_init(void) 400 { 401 int err, i; 402 unsigned short addr = 0; 403 404 for (i = 0; i < ARRAY_SIZE(sch311x_ioports); i++) 405 if (sch311x_detect(sch311x_ioports[i], &addr) == 0) 406 break; 407 408 if (!addr) 409 return -ENODEV; 410 411 err = platform_driver_register(&sch311x_gpio_driver); 412 if (err) 413 return err; 414 415 err = sch311x_gpio_pdev_add(addr); 416 if (err) 417 goto unreg_platform_driver; 418 419 return 0; 420 421 unreg_platform_driver: 422 platform_driver_unregister(&sch311x_gpio_driver); 423 return err; 424 } 425 426 static void __exit sch311x_gpio_exit(void) 427 { 428 platform_device_unregister(sch311x_gpio_pdev); 429 platform_driver_unregister(&sch311x_gpio_driver); 430 } 431 432 module_init(sch311x_gpio_init); 433 module_exit(sch311x_gpio_exit); 434 435 MODULE_AUTHOR("Bruno Randolf <br1@einfach.org>"); 436 MODULE_DESCRIPTION("SMSC SCH311x GPIO Driver"); 437 MODULE_LICENSE("GPL"); 438 MODULE_ALIAS("platform:gpio-sch311x"); 439