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

Configure Feed

Select the types of activity you want to include in your feed.

at v6.1-rc8 627 lines 17 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * htc-i2cpld.c 4 * Chip driver for an unknown CPLD chip found on omap850 HTC devices like 5 * the HTC Wizard and HTC Herald. 6 * The cpld is located on the i2c bus and acts as an input/output GPIO 7 * extender. 8 * 9 * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com> 10 * 11 * Based on work done in the linwizard project 12 * Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com> 13 */ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/interrupt.h> 18#include <linux/platform_device.h> 19#include <linux/i2c.h> 20#include <linux/irq.h> 21#include <linux/spinlock.h> 22#include <linux/htcpld.h> 23#include <linux/gpio/driver.h> 24#include <linux/gpio/machine.h> 25#include <linux/gpio/consumer.h> 26#include <linux/slab.h> 27 28struct htcpld_chip { 29 spinlock_t lock; 30 31 /* chip info */ 32 u8 reset; 33 u8 addr; 34 struct device *dev; 35 struct i2c_client *client; 36 37 /* Output details */ 38 u8 cache_out; 39 struct gpio_chip chip_out; 40 41 /* Input details */ 42 u8 cache_in; 43 struct gpio_chip chip_in; 44 45 u16 irqs_enabled; 46 uint irq_start; 47 int nirqs; 48 49 unsigned int flow_type; 50 /* 51 * Work structure to allow for setting values outside of any 52 * possible interrupt context 53 */ 54 struct work_struct set_val_work; 55}; 56 57struct htcpld_data { 58 /* irq info */ 59 u16 irqs_enabled; 60 uint irq_start; 61 int nirqs; 62 uint chained_irq; 63 struct gpio_desc *int_reset_gpio_hi; 64 struct gpio_desc *int_reset_gpio_lo; 65 66 /* htcpld info */ 67 struct htcpld_chip *chip; 68 unsigned int nchips; 69}; 70 71/* There does not appear to be a way to proactively mask interrupts 72 * on the htcpld chip itself. So, we simply ignore interrupts that 73 * aren't desired. */ 74static void htcpld_mask(struct irq_data *data) 75{ 76 struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); 77 chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start)); 78 pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled); 79} 80static void htcpld_unmask(struct irq_data *data) 81{ 82 struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); 83 chip->irqs_enabled |= 1 << (data->irq - chip->irq_start); 84 pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled); 85} 86 87static int htcpld_set_type(struct irq_data *data, unsigned int flags) 88{ 89 struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); 90 91 if (flags & ~IRQ_TYPE_SENSE_MASK) 92 return -EINVAL; 93 94 /* We only allow edge triggering */ 95 if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)) 96 return -EINVAL; 97 98 chip->flow_type = flags; 99 return 0; 100} 101 102static struct irq_chip htcpld_muxed_chip = { 103 .name = "htcpld", 104 .irq_mask = htcpld_mask, 105 .irq_unmask = htcpld_unmask, 106 .irq_set_type = htcpld_set_type, 107}; 108 109/* To properly dispatch IRQ events, we need to read from the 110 * chip. This is an I2C action that could possibly sleep 111 * (which is bad in interrupt context) -- so we use a threaded 112 * interrupt handler to get around that. 113 */ 114static irqreturn_t htcpld_handler(int irq, void *dev) 115{ 116 struct htcpld_data *htcpld = dev; 117 unsigned int i; 118 unsigned long flags; 119 int irqpin; 120 121 if (!htcpld) { 122 pr_debug("htcpld is null in ISR\n"); 123 return IRQ_HANDLED; 124 } 125 126 /* 127 * For each chip, do a read of the chip and trigger any interrupts 128 * desired. The interrupts will be triggered from LSB to MSB (i.e. 129 * bit 0 first, then bit 1, etc.) 130 * 131 * For chips that have no interrupt range specified, just skip 'em. 132 */ 133 for (i = 0; i < htcpld->nchips; i++) { 134 struct htcpld_chip *chip = &htcpld->chip[i]; 135 struct i2c_client *client; 136 int val; 137 unsigned long uval, old_val; 138 139 if (!chip) { 140 pr_debug("chip %d is null in ISR\n", i); 141 continue; 142 } 143 144 if (chip->nirqs == 0) 145 continue; 146 147 client = chip->client; 148 if (!client) { 149 pr_debug("client %d is null in ISR\n", i); 150 continue; 151 } 152 153 /* Scan the chip */ 154 val = i2c_smbus_read_byte_data(client, chip->cache_out); 155 if (val < 0) { 156 /* Throw a warning and skip this chip */ 157 dev_warn(chip->dev, "Unable to read from chip: %d\n", 158 val); 159 continue; 160 } 161 162 uval = (unsigned long)val; 163 164 spin_lock_irqsave(&chip->lock, flags); 165 166 /* Save away the old value so we can compare it */ 167 old_val = chip->cache_in; 168 169 /* Write the new value */ 170 chip->cache_in = uval; 171 172 spin_unlock_irqrestore(&chip->lock, flags); 173 174 /* 175 * For each bit in the data (starting at bit 0), trigger 176 * associated interrupts. 177 */ 178 for (irqpin = 0; irqpin < chip->nirqs; irqpin++) { 179 unsigned oldb, newb, type = chip->flow_type; 180 181 irq = chip->irq_start + irqpin; 182 183 /* Run the IRQ handler, but only if the bit value 184 * changed, and the proper flags are set */ 185 oldb = (old_val >> irqpin) & 1; 186 newb = (uval >> irqpin) & 1; 187 188 if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) || 189 (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) { 190 pr_debug("fire IRQ %d\n", irqpin); 191 generic_handle_irq(irq); 192 } 193 } 194 } 195 196 /* 197 * In order to continue receiving interrupts, the int_reset_gpio must 198 * be asserted. 199 */ 200 if (htcpld->int_reset_gpio_hi) 201 gpiod_set_value(htcpld->int_reset_gpio_hi, 1); 202 if (htcpld->int_reset_gpio_lo) 203 gpiod_set_value(htcpld->int_reset_gpio_lo, 0); 204 205 return IRQ_HANDLED; 206} 207 208/* 209 * The GPIO set routines can be called from interrupt context, especially if, 210 * for example they're attached to the led-gpio framework and a trigger is 211 * enabled. As such, we declared work above in the htcpld_chip structure, 212 * and that work is scheduled in the set routine. The kernel can then run 213 * the I2C functions, which will sleep, in process context. 214 */ 215static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) 216{ 217 struct i2c_client *client; 218 struct htcpld_chip *chip_data = gpiochip_get_data(chip); 219 unsigned long flags; 220 221 client = chip_data->client; 222 if (!client) 223 return; 224 225 spin_lock_irqsave(&chip_data->lock, flags); 226 if (val) 227 chip_data->cache_out |= (1 << offset); 228 else 229 chip_data->cache_out &= ~(1 << offset); 230 spin_unlock_irqrestore(&chip_data->lock, flags); 231 232 schedule_work(&(chip_data->set_val_work)); 233} 234 235static void htcpld_chip_set_ni(struct work_struct *work) 236{ 237 struct htcpld_chip *chip_data; 238 struct i2c_client *client; 239 240 chip_data = container_of(work, struct htcpld_chip, set_val_work); 241 client = chip_data->client; 242 i2c_smbus_read_byte_data(client, chip_data->cache_out); 243} 244 245static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) 246{ 247 struct htcpld_chip *chip_data = gpiochip_get_data(chip); 248 u8 cache; 249 250 if (!strncmp(chip->label, "htcpld-out", 10)) { 251 cache = chip_data->cache_out; 252 } else if (!strncmp(chip->label, "htcpld-in", 9)) { 253 cache = chip_data->cache_in; 254 } else 255 return -EINVAL; 256 257 return (cache >> offset) & 1; 258} 259 260static int htcpld_direction_output(struct gpio_chip *chip, 261 unsigned offset, int value) 262{ 263 htcpld_chip_set(chip, offset, value); 264 return 0; 265} 266 267static int htcpld_direction_input(struct gpio_chip *chip, 268 unsigned offset) 269{ 270 /* 271 * No-op: this function can only be called on the input chip. 272 * We do however make sure the offset is within range. 273 */ 274 return (offset < chip->ngpio) ? 0 : -EINVAL; 275} 276 277static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) 278{ 279 struct htcpld_chip *chip_data = gpiochip_get_data(chip); 280 281 if (offset < chip_data->nirqs) 282 return chip_data->irq_start + offset; 283 else 284 return -EINVAL; 285} 286 287static void htcpld_chip_reset(struct i2c_client *client) 288{ 289 struct htcpld_chip *chip_data = i2c_get_clientdata(client); 290 if (!chip_data) 291 return; 292 293 i2c_smbus_read_byte_data( 294 client, (chip_data->cache_out = chip_data->reset)); 295} 296 297static int htcpld_setup_chip_irq( 298 struct platform_device *pdev, 299 int chip_index) 300{ 301 struct htcpld_data *htcpld; 302 struct htcpld_chip *chip; 303 unsigned int irq, irq_end; 304 305 /* Get the platform and driver data */ 306 htcpld = platform_get_drvdata(pdev); 307 chip = &htcpld->chip[chip_index]; 308 309 /* Setup irq handlers */ 310 irq_end = chip->irq_start + chip->nirqs; 311 for (irq = chip->irq_start; irq < irq_end; irq++) { 312 irq_set_chip_and_handler(irq, &htcpld_muxed_chip, 313 handle_simple_irq); 314 irq_set_chip_data(irq, chip); 315 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); 316 } 317 318 return 0; 319} 320 321static int htcpld_register_chip_i2c( 322 struct platform_device *pdev, 323 int chip_index) 324{ 325 struct htcpld_data *htcpld; 326 struct device *dev = &pdev->dev; 327 struct htcpld_core_platform_data *pdata; 328 struct htcpld_chip *chip; 329 struct htcpld_chip_platform_data *plat_chip_data; 330 struct i2c_adapter *adapter; 331 struct i2c_client *client; 332 struct i2c_board_info info; 333 334 /* Get the platform and driver data */ 335 pdata = dev_get_platdata(dev); 336 htcpld = platform_get_drvdata(pdev); 337 chip = &htcpld->chip[chip_index]; 338 plat_chip_data = &pdata->chip[chip_index]; 339 340 adapter = i2c_get_adapter(pdata->i2c_adapter_id); 341 if (!adapter) { 342 /* Eek, no such I2C adapter! Bail out. */ 343 dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n", 344 plat_chip_data->addr, pdata->i2c_adapter_id); 345 return -ENODEV; 346 } 347 348 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 349 dev_warn(dev, "i2c adapter %d non-functional\n", 350 pdata->i2c_adapter_id); 351 i2c_put_adapter(adapter); 352 return -EINVAL; 353 } 354 355 memset(&info, 0, sizeof(struct i2c_board_info)); 356 info.addr = plat_chip_data->addr; 357 strscpy(info.type, "htcpld-chip", I2C_NAME_SIZE); 358 info.platform_data = chip; 359 360 /* Add the I2C device. This calls the probe() function. */ 361 client = i2c_new_client_device(adapter, &info); 362 if (IS_ERR(client)) { 363 /* I2C device registration failed, contineu with the next */ 364 dev_warn(dev, "Unable to add I2C device for 0x%x\n", 365 plat_chip_data->addr); 366 i2c_put_adapter(adapter); 367 return PTR_ERR(client); 368 } 369 370 i2c_set_clientdata(client, chip); 371 snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr); 372 chip->client = client; 373 374 /* Reset the chip */ 375 htcpld_chip_reset(client); 376 chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out); 377 378 return 0; 379} 380 381static void htcpld_unregister_chip_i2c( 382 struct platform_device *pdev, 383 int chip_index) 384{ 385 struct htcpld_data *htcpld; 386 struct htcpld_chip *chip; 387 388 /* Get the platform and driver data */ 389 htcpld = platform_get_drvdata(pdev); 390 chip = &htcpld->chip[chip_index]; 391 392 i2c_unregister_device(chip->client); 393} 394 395static int htcpld_register_chip_gpio( 396 struct platform_device *pdev, 397 int chip_index) 398{ 399 struct htcpld_data *htcpld; 400 struct device *dev = &pdev->dev; 401 struct htcpld_core_platform_data *pdata; 402 struct htcpld_chip *chip; 403 struct htcpld_chip_platform_data *plat_chip_data; 404 struct gpio_chip *gpio_chip; 405 int ret = 0; 406 407 /* Get the platform and driver data */ 408 pdata = dev_get_platdata(dev); 409 htcpld = platform_get_drvdata(pdev); 410 chip = &htcpld->chip[chip_index]; 411 plat_chip_data = &pdata->chip[chip_index]; 412 413 /* Setup the GPIO chips */ 414 gpio_chip = &(chip->chip_out); 415 gpio_chip->label = "htcpld-out"; 416 gpio_chip->parent = dev; 417 gpio_chip->owner = THIS_MODULE; 418 gpio_chip->get = htcpld_chip_get; 419 gpio_chip->set = htcpld_chip_set; 420 gpio_chip->direction_input = NULL; 421 gpio_chip->direction_output = htcpld_direction_output; 422 gpio_chip->base = plat_chip_data->gpio_out_base; 423 gpio_chip->ngpio = plat_chip_data->num_gpios; 424 425 gpio_chip = &(chip->chip_in); 426 gpio_chip->label = "htcpld-in"; 427 gpio_chip->parent = dev; 428 gpio_chip->owner = THIS_MODULE; 429 gpio_chip->get = htcpld_chip_get; 430 gpio_chip->set = NULL; 431 gpio_chip->direction_input = htcpld_direction_input; 432 gpio_chip->direction_output = NULL; 433 gpio_chip->to_irq = htcpld_chip_to_irq; 434 gpio_chip->base = plat_chip_data->gpio_in_base; 435 gpio_chip->ngpio = plat_chip_data->num_gpios; 436 437 /* Add the GPIO chips */ 438 ret = gpiochip_add_data(&(chip->chip_out), chip); 439 if (ret) { 440 dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n", 441 plat_chip_data->addr, ret); 442 return ret; 443 } 444 445 ret = gpiochip_add_data(&(chip->chip_in), chip); 446 if (ret) { 447 dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n", 448 plat_chip_data->addr, ret); 449 gpiochip_remove(&(chip->chip_out)); 450 return ret; 451 } 452 453 return 0; 454} 455 456static int htcpld_setup_chips(struct platform_device *pdev) 457{ 458 struct htcpld_data *htcpld; 459 struct device *dev = &pdev->dev; 460 struct htcpld_core_platform_data *pdata; 461 int i; 462 463 /* Get the platform and driver data */ 464 pdata = dev_get_platdata(dev); 465 htcpld = platform_get_drvdata(pdev); 466 467 /* Setup each chip's output GPIOs */ 468 htcpld->nchips = pdata->num_chip; 469 htcpld->chip = devm_kcalloc(dev, 470 htcpld->nchips, 471 sizeof(struct htcpld_chip), 472 GFP_KERNEL); 473 if (!htcpld->chip) 474 return -ENOMEM; 475 476 /* Add the chips as best we can */ 477 for (i = 0; i < htcpld->nchips; i++) { 478 int ret; 479 480 /* Setup the HTCPLD chips */ 481 htcpld->chip[i].reset = pdata->chip[i].reset; 482 htcpld->chip[i].cache_out = pdata->chip[i].reset; 483 htcpld->chip[i].cache_in = 0; 484 htcpld->chip[i].dev = dev; 485 htcpld->chip[i].irq_start = pdata->chip[i].irq_base; 486 htcpld->chip[i].nirqs = pdata->chip[i].num_irqs; 487 488 INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni); 489 spin_lock_init(&(htcpld->chip[i].lock)); 490 491 /* Setup the interrupts for the chip */ 492 if (htcpld->chained_irq) { 493 ret = htcpld_setup_chip_irq(pdev, i); 494 if (ret) 495 continue; 496 } 497 498 /* Register the chip with I2C */ 499 ret = htcpld_register_chip_i2c(pdev, i); 500 if (ret) 501 continue; 502 503 504 /* Register the chips with the GPIO subsystem */ 505 ret = htcpld_register_chip_gpio(pdev, i); 506 if (ret) { 507 /* Unregister the chip from i2c and continue */ 508 htcpld_unregister_chip_i2c(pdev, i); 509 continue; 510 } 511 512 dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr); 513 } 514 515 return 0; 516} 517 518static int htcpld_core_probe(struct platform_device *pdev) 519{ 520 struct htcpld_data *htcpld; 521 struct device *dev = &pdev->dev; 522 struct htcpld_core_platform_data *pdata; 523 struct resource *res; 524 int ret = 0; 525 526 if (!dev) 527 return -ENODEV; 528 529 pdata = dev_get_platdata(dev); 530 if (!pdata) { 531 dev_warn(dev, "Platform data not found for htcpld core!\n"); 532 return -ENXIO; 533 } 534 535 htcpld = devm_kzalloc(dev, sizeof(struct htcpld_data), GFP_KERNEL); 536 if (!htcpld) 537 return -ENOMEM; 538 539 /* Find chained irq */ 540 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 541 if (res) { 542 int flags; 543 htcpld->chained_irq = res->start; 544 545 /* Setup the chained interrupt handler */ 546 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | 547 IRQF_ONESHOT; 548 ret = request_threaded_irq(htcpld->chained_irq, 549 NULL, htcpld_handler, 550 flags, pdev->name, htcpld); 551 if (ret) { 552 dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret); 553 return ret; 554 } else 555 device_init_wakeup(dev, 0); 556 } 557 558 /* Set the driver data */ 559 platform_set_drvdata(pdev, htcpld); 560 561 /* Setup the htcpld chips */ 562 ret = htcpld_setup_chips(pdev); 563 if (ret) 564 return ret; 565 566 /* Request the GPIO(s) for the int reset and set them up */ 567 htcpld->int_reset_gpio_hi = gpiochip_request_own_desc(&htcpld->chip[2].chip_out, 568 7, "htcpld-core", GPIO_ACTIVE_HIGH, 569 GPIOD_OUT_HIGH); 570 if (IS_ERR(htcpld->int_reset_gpio_hi)) { 571 /* 572 * If it failed, that sucks, but we can probably 573 * continue on without it. 574 */ 575 htcpld->int_reset_gpio_hi = NULL; 576 dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n"); 577 } 578 579 htcpld->int_reset_gpio_lo = gpiochip_request_own_desc(&htcpld->chip[2].chip_out, 580 0, "htcpld-core", GPIO_ACTIVE_HIGH, 581 GPIOD_OUT_LOW); 582 if (IS_ERR(htcpld->int_reset_gpio_lo)) { 583 /* 584 * If it failed, that sucks, but we can probably 585 * continue on without it. 586 */ 587 htcpld->int_reset_gpio_lo = NULL; 588 dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n"); 589 } 590 591 dev_info(dev, "Initialized successfully\n"); 592 return 0; 593} 594 595/* The I2C Driver -- used internally */ 596static const struct i2c_device_id htcpld_chip_id[] = { 597 { "htcpld-chip", 0 }, 598 { } 599}; 600 601static struct i2c_driver htcpld_chip_driver = { 602 .driver = { 603 .name = "htcpld-chip", 604 }, 605 .id_table = htcpld_chip_id, 606}; 607 608/* The Core Driver */ 609static struct platform_driver htcpld_core_driver = { 610 .driver = { 611 .name = "i2c-htcpld", 612 }, 613}; 614 615static int __init htcpld_core_init(void) 616{ 617 int ret; 618 619 /* Register the I2C Chip driver */ 620 ret = i2c_add_driver(&htcpld_chip_driver); 621 if (ret) 622 return ret; 623 624 /* Probe for our chips */ 625 return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); 626} 627device_initcall(htcpld_core_init);