Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  htc-i2cpld.c
0004  *  Chip driver for an unknown CPLD chip found on omap850 HTC devices like
0005  *  the HTC Wizard and HTC Herald.
0006  *  The cpld is located on the i2c bus and acts as an input/output GPIO
0007  *  extender.
0008  *
0009  *  Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
0010  *
0011  *  Based on work done in the linwizard project
0012  *  Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com>
0013  */
0014 
0015 #include <linux/kernel.h>
0016 #include <linux/init.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/i2c.h>
0020 #include <linux/irq.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/htcpld.h>
0023 #include <linux/gpio.h>
0024 #include <linux/slab.h>
0025 
0026 struct htcpld_chip {
0027     spinlock_t              lock;
0028 
0029     /* chip info */
0030     u8                      reset;
0031     u8                      addr;
0032     struct device           *dev;
0033     struct i2c_client   *client;
0034 
0035     /* Output details */
0036     u8                      cache_out;
0037     struct gpio_chip        chip_out;
0038 
0039     /* Input details */
0040     u8                      cache_in;
0041     struct gpio_chip        chip_in;
0042 
0043     u16                     irqs_enabled;
0044     uint                    irq_start;
0045     int                     nirqs;
0046 
0047     unsigned int        flow_type;
0048     /*
0049      * Work structure to allow for setting values outside of any
0050      * possible interrupt context
0051      */
0052     struct work_struct set_val_work;
0053 };
0054 
0055 struct htcpld_data {
0056     /* irq info */
0057     u16                irqs_enabled;
0058     uint               irq_start;
0059     int                nirqs;
0060     uint               chained_irq;
0061     unsigned int       int_reset_gpio_hi;
0062     unsigned int       int_reset_gpio_lo;
0063 
0064     /* htcpld info */
0065     struct htcpld_chip *chip;
0066     unsigned int       nchips;
0067 };
0068 
0069 /* There does not appear to be a way to proactively mask interrupts
0070  * on the htcpld chip itself.  So, we simply ignore interrupts that
0071  * aren't desired. */
0072 static void htcpld_mask(struct irq_data *data)
0073 {
0074     struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
0075     chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start));
0076     pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled);
0077 }
0078 static void htcpld_unmask(struct irq_data *data)
0079 {
0080     struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
0081     chip->irqs_enabled |= 1 << (data->irq - chip->irq_start);
0082     pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled);
0083 }
0084 
0085 static int htcpld_set_type(struct irq_data *data, unsigned int flags)
0086 {
0087     struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
0088 
0089     if (flags & ~IRQ_TYPE_SENSE_MASK)
0090         return -EINVAL;
0091 
0092     /* We only allow edge triggering */
0093     if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
0094         return -EINVAL;
0095 
0096     chip->flow_type = flags;
0097     return 0;
0098 }
0099 
0100 static struct irq_chip htcpld_muxed_chip = {
0101     .name         = "htcpld",
0102     .irq_mask     = htcpld_mask,
0103     .irq_unmask   = htcpld_unmask,
0104     .irq_set_type = htcpld_set_type,
0105 };
0106 
0107 /* To properly dispatch IRQ events, we need to read from the
0108  * chip.  This is an I2C action that could possibly sleep
0109  * (which is bad in interrupt context) -- so we use a threaded
0110  * interrupt handler to get around that.
0111  */
0112 static irqreturn_t htcpld_handler(int irq, void *dev)
0113 {
0114     struct htcpld_data *htcpld = dev;
0115     unsigned int i;
0116     unsigned long flags;
0117     int irqpin;
0118 
0119     if (!htcpld) {
0120         pr_debug("htcpld is null in ISR\n");
0121         return IRQ_HANDLED;
0122     }
0123 
0124     /*
0125      * For each chip, do a read of the chip and trigger any interrupts
0126      * desired.  The interrupts will be triggered from LSB to MSB (i.e.
0127      * bit 0 first, then bit 1, etc.)
0128      *
0129      * For chips that have no interrupt range specified, just skip 'em.
0130      */
0131     for (i = 0; i < htcpld->nchips; i++) {
0132         struct htcpld_chip *chip = &htcpld->chip[i];
0133         struct i2c_client *client;
0134         int val;
0135         unsigned long uval, old_val;
0136 
0137         if (!chip) {
0138             pr_debug("chip %d is null in ISR\n", i);
0139             continue;
0140         }
0141 
0142         if (chip->nirqs == 0)
0143             continue;
0144 
0145         client = chip->client;
0146         if (!client) {
0147             pr_debug("client %d is null in ISR\n", i);
0148             continue;
0149         }
0150 
0151         /* Scan the chip */
0152         val = i2c_smbus_read_byte_data(client, chip->cache_out);
0153         if (val < 0) {
0154             /* Throw a warning and skip this chip */
0155             dev_warn(chip->dev, "Unable to read from chip: %d\n",
0156                  val);
0157             continue;
0158         }
0159 
0160         uval = (unsigned long)val;
0161 
0162         spin_lock_irqsave(&chip->lock, flags);
0163 
0164         /* Save away the old value so we can compare it */
0165         old_val = chip->cache_in;
0166 
0167         /* Write the new value */
0168         chip->cache_in = uval;
0169 
0170         spin_unlock_irqrestore(&chip->lock, flags);
0171 
0172         /*
0173          * For each bit in the data (starting at bit 0), trigger
0174          * associated interrupts.
0175          */
0176         for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
0177             unsigned oldb, newb, type = chip->flow_type;
0178 
0179             irq = chip->irq_start + irqpin;
0180 
0181             /* Run the IRQ handler, but only if the bit value
0182              * changed, and the proper flags are set */
0183             oldb = (old_val >> irqpin) & 1;
0184             newb = (uval >> irqpin) & 1;
0185 
0186             if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) ||
0187                 (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) {
0188                 pr_debug("fire IRQ %d\n", irqpin);
0189                 generic_handle_irq(irq);
0190             }
0191         }
0192     }
0193 
0194     /*
0195      * In order to continue receiving interrupts, the int_reset_gpio must
0196      * be asserted.
0197      */
0198     if (htcpld->int_reset_gpio_hi)
0199         gpio_set_value(htcpld->int_reset_gpio_hi, 1);
0200     if (htcpld->int_reset_gpio_lo)
0201         gpio_set_value(htcpld->int_reset_gpio_lo, 0);
0202 
0203     return IRQ_HANDLED;
0204 }
0205 
0206 /*
0207  * The GPIO set routines can be called from interrupt context, especially if,
0208  * for example they're attached to the led-gpio framework and a trigger is
0209  * enabled.  As such, we declared work above in the htcpld_chip structure,
0210  * and that work is scheduled in the set routine.  The kernel can then run
0211  * the I2C functions, which will sleep, in process context.
0212  */
0213 static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
0214 {
0215     struct i2c_client *client;
0216     struct htcpld_chip *chip_data = gpiochip_get_data(chip);
0217     unsigned long flags;
0218 
0219     client = chip_data->client;
0220     if (!client)
0221         return;
0222 
0223     spin_lock_irqsave(&chip_data->lock, flags);
0224     if (val)
0225         chip_data->cache_out |= (1 << offset);
0226     else
0227         chip_data->cache_out &= ~(1 << offset);
0228     spin_unlock_irqrestore(&chip_data->lock, flags);
0229 
0230     schedule_work(&(chip_data->set_val_work));
0231 }
0232 
0233 static void htcpld_chip_set_ni(struct work_struct *work)
0234 {
0235     struct htcpld_chip *chip_data;
0236     struct i2c_client *client;
0237 
0238     chip_data = container_of(work, struct htcpld_chip, set_val_work);
0239     client = chip_data->client;
0240     i2c_smbus_read_byte_data(client, chip_data->cache_out);
0241 }
0242 
0243 static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
0244 {
0245     struct htcpld_chip *chip_data = gpiochip_get_data(chip);
0246     u8 cache;
0247 
0248     if (!strncmp(chip->label, "htcpld-out", 10)) {
0249         cache = chip_data->cache_out;
0250     } else if (!strncmp(chip->label, "htcpld-in", 9)) {
0251         cache = chip_data->cache_in;
0252     } else
0253         return -EINVAL;
0254 
0255     return (cache >> offset) & 1;
0256 }
0257 
0258 static int htcpld_direction_output(struct gpio_chip *chip,
0259                     unsigned offset, int value)
0260 {
0261     htcpld_chip_set(chip, offset, value);
0262     return 0;
0263 }
0264 
0265 static int htcpld_direction_input(struct gpio_chip *chip,
0266                     unsigned offset)
0267 {
0268     /*
0269      * No-op: this function can only be called on the input chip.
0270      * We do however make sure the offset is within range.
0271      */
0272     return (offset < chip->ngpio) ? 0 : -EINVAL;
0273 }
0274 
0275 static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
0276 {
0277     struct htcpld_chip *chip_data = gpiochip_get_data(chip);
0278 
0279     if (offset < chip_data->nirqs)
0280         return chip_data->irq_start + offset;
0281     else
0282         return -EINVAL;
0283 }
0284 
0285 static void htcpld_chip_reset(struct i2c_client *client)
0286 {
0287     struct htcpld_chip *chip_data = i2c_get_clientdata(client);
0288     if (!chip_data)
0289         return;
0290 
0291     i2c_smbus_read_byte_data(
0292         client, (chip_data->cache_out = chip_data->reset));
0293 }
0294 
0295 static int htcpld_setup_chip_irq(
0296         struct platform_device *pdev,
0297         int chip_index)
0298 {
0299     struct htcpld_data *htcpld;
0300     struct htcpld_chip *chip;
0301     unsigned int irq, irq_end;
0302 
0303     /* Get the platform and driver data */
0304     htcpld = platform_get_drvdata(pdev);
0305     chip = &htcpld->chip[chip_index];
0306 
0307     /* Setup irq handlers */
0308     irq_end = chip->irq_start + chip->nirqs;
0309     for (irq = chip->irq_start; irq < irq_end; irq++) {
0310         irq_set_chip_and_handler(irq, &htcpld_muxed_chip,
0311                      handle_simple_irq);
0312         irq_set_chip_data(irq, chip);
0313         irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0314     }
0315 
0316     return 0;
0317 }
0318 
0319 static int htcpld_register_chip_i2c(
0320         struct platform_device *pdev,
0321         int chip_index)
0322 {
0323     struct htcpld_data *htcpld;
0324     struct device *dev = &pdev->dev;
0325     struct htcpld_core_platform_data *pdata;
0326     struct htcpld_chip *chip;
0327     struct htcpld_chip_platform_data *plat_chip_data;
0328     struct i2c_adapter *adapter;
0329     struct i2c_client *client;
0330     struct i2c_board_info info;
0331 
0332     /* Get the platform and driver data */
0333     pdata = dev_get_platdata(dev);
0334     htcpld = platform_get_drvdata(pdev);
0335     chip = &htcpld->chip[chip_index];
0336     plat_chip_data = &pdata->chip[chip_index];
0337 
0338     adapter = i2c_get_adapter(pdata->i2c_adapter_id);
0339     if (!adapter) {
0340         /* Eek, no such I2C adapter!  Bail out. */
0341         dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
0342              plat_chip_data->addr, pdata->i2c_adapter_id);
0343         return -ENODEV;
0344     }
0345 
0346     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
0347         dev_warn(dev, "i2c adapter %d non-functional\n",
0348              pdata->i2c_adapter_id);
0349         i2c_put_adapter(adapter);
0350         return -EINVAL;
0351     }
0352 
0353     memset(&info, 0, sizeof(struct i2c_board_info));
0354     info.addr = plat_chip_data->addr;
0355     strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
0356     info.platform_data = chip;
0357 
0358     /* Add the I2C device.  This calls the probe() function. */
0359     client = i2c_new_client_device(adapter, &info);
0360     if (IS_ERR(client)) {
0361         /* I2C device registration failed, contineu with the next */
0362         dev_warn(dev, "Unable to add I2C device for 0x%x\n",
0363              plat_chip_data->addr);
0364         i2c_put_adapter(adapter);
0365         return PTR_ERR(client);
0366     }
0367 
0368     i2c_set_clientdata(client, chip);
0369     snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr);
0370     chip->client = client;
0371 
0372     /* Reset the chip */
0373     htcpld_chip_reset(client);
0374     chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
0375 
0376     return 0;
0377 }
0378 
0379 static void htcpld_unregister_chip_i2c(
0380         struct platform_device *pdev,
0381         int chip_index)
0382 {
0383     struct htcpld_data *htcpld;
0384     struct htcpld_chip *chip;
0385 
0386     /* Get the platform and driver data */
0387     htcpld = platform_get_drvdata(pdev);
0388     chip = &htcpld->chip[chip_index];
0389 
0390     i2c_unregister_device(chip->client);
0391 }
0392 
0393 static int htcpld_register_chip_gpio(
0394         struct platform_device *pdev,
0395         int chip_index)
0396 {
0397     struct htcpld_data *htcpld;
0398     struct device *dev = &pdev->dev;
0399     struct htcpld_core_platform_data *pdata;
0400     struct htcpld_chip *chip;
0401     struct htcpld_chip_platform_data *plat_chip_data;
0402     struct gpio_chip *gpio_chip;
0403     int ret = 0;
0404 
0405     /* Get the platform and driver data */
0406     pdata = dev_get_platdata(dev);
0407     htcpld = platform_get_drvdata(pdev);
0408     chip = &htcpld->chip[chip_index];
0409     plat_chip_data = &pdata->chip[chip_index];
0410 
0411     /* Setup the GPIO chips */
0412     gpio_chip = &(chip->chip_out);
0413     gpio_chip->label           = "htcpld-out";
0414     gpio_chip->parent             = dev;
0415     gpio_chip->owner           = THIS_MODULE;
0416     gpio_chip->get             = htcpld_chip_get;
0417     gpio_chip->set             = htcpld_chip_set;
0418     gpio_chip->direction_input = NULL;
0419     gpio_chip->direction_output = htcpld_direction_output;
0420     gpio_chip->base            = plat_chip_data->gpio_out_base;
0421     gpio_chip->ngpio           = plat_chip_data->num_gpios;
0422 
0423     gpio_chip = &(chip->chip_in);
0424     gpio_chip->label           = "htcpld-in";
0425     gpio_chip->parent             = dev;
0426     gpio_chip->owner           = THIS_MODULE;
0427     gpio_chip->get             = htcpld_chip_get;
0428     gpio_chip->set             = NULL;
0429     gpio_chip->direction_input = htcpld_direction_input;
0430     gpio_chip->direction_output = NULL;
0431     gpio_chip->to_irq          = htcpld_chip_to_irq;
0432     gpio_chip->base            = plat_chip_data->gpio_in_base;
0433     gpio_chip->ngpio           = plat_chip_data->num_gpios;
0434 
0435     /* Add the GPIO chips */
0436     ret = gpiochip_add_data(&(chip->chip_out), chip);
0437     if (ret) {
0438         dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
0439              plat_chip_data->addr, ret);
0440         return ret;
0441     }
0442 
0443     ret = gpiochip_add_data(&(chip->chip_in), chip);
0444     if (ret) {
0445         dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
0446              plat_chip_data->addr, ret);
0447         gpiochip_remove(&(chip->chip_out));
0448         return ret;
0449     }
0450 
0451     return 0;
0452 }
0453 
0454 static int htcpld_setup_chips(struct platform_device *pdev)
0455 {
0456     struct htcpld_data *htcpld;
0457     struct device *dev = &pdev->dev;
0458     struct htcpld_core_platform_data *pdata;
0459     int i;
0460 
0461     /* Get the platform and driver data */
0462     pdata = dev_get_platdata(dev);
0463     htcpld = platform_get_drvdata(pdev);
0464 
0465     /* Setup each chip's output GPIOs */
0466     htcpld->nchips = pdata->num_chip;
0467     htcpld->chip = devm_kcalloc(dev,
0468                     htcpld->nchips,
0469                     sizeof(struct htcpld_chip),
0470                     GFP_KERNEL);
0471     if (!htcpld->chip)
0472         return -ENOMEM;
0473 
0474     /* Add the chips as best we can */
0475     for (i = 0; i < htcpld->nchips; i++) {
0476         int ret;
0477 
0478         /* Setup the HTCPLD chips */
0479         htcpld->chip[i].reset = pdata->chip[i].reset;
0480         htcpld->chip[i].cache_out = pdata->chip[i].reset;
0481         htcpld->chip[i].cache_in = 0;
0482         htcpld->chip[i].dev = dev;
0483         htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
0484         htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
0485 
0486         INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
0487         spin_lock_init(&(htcpld->chip[i].lock));
0488 
0489         /* Setup the interrupts for the chip */
0490         if (htcpld->chained_irq) {
0491             ret = htcpld_setup_chip_irq(pdev, i);
0492             if (ret)
0493                 continue;
0494         }
0495 
0496         /* Register the chip with I2C */
0497         ret = htcpld_register_chip_i2c(pdev, i);
0498         if (ret)
0499             continue;
0500 
0501 
0502         /* Register the chips with the GPIO subsystem */
0503         ret = htcpld_register_chip_gpio(pdev, i);
0504         if (ret) {
0505             /* Unregister the chip from i2c and continue */
0506             htcpld_unregister_chip_i2c(pdev, i);
0507             continue;
0508         }
0509 
0510         dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
0511     }
0512 
0513     return 0;
0514 }
0515 
0516 static int htcpld_core_probe(struct platform_device *pdev)
0517 {
0518     struct htcpld_data *htcpld;
0519     struct device *dev = &pdev->dev;
0520     struct htcpld_core_platform_data *pdata;
0521     struct resource *res;
0522     int ret = 0;
0523 
0524     if (!dev)
0525         return -ENODEV;
0526 
0527     pdata = dev_get_platdata(dev);
0528     if (!pdata) {
0529         dev_warn(dev, "Platform data not found for htcpld core!\n");
0530         return -ENXIO;
0531     }
0532 
0533     htcpld = devm_kzalloc(dev, sizeof(struct htcpld_data), GFP_KERNEL);
0534     if (!htcpld)
0535         return -ENOMEM;
0536 
0537     /* Find chained irq */
0538     res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
0539     if (res) {
0540         int flags;
0541         htcpld->chained_irq = res->start;
0542 
0543         /* Setup the chained interrupt handler */
0544         flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
0545             IRQF_ONESHOT;
0546         ret = request_threaded_irq(htcpld->chained_irq,
0547                        NULL, htcpld_handler,
0548                        flags, pdev->name, htcpld);
0549         if (ret) {
0550             dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
0551             return ret;
0552         } else
0553             device_init_wakeup(dev, 0);
0554     }
0555 
0556     /* Set the driver data */
0557     platform_set_drvdata(pdev, htcpld);
0558 
0559     /* Setup the htcpld chips */
0560     ret = htcpld_setup_chips(pdev);
0561     if (ret)
0562         return ret;
0563 
0564     /* Request the GPIO(s) for the int reset and set them up */
0565     if (pdata->int_reset_gpio_hi) {
0566         ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core");
0567         if (ret) {
0568             /*
0569              * If it failed, that sucks, but we can probably
0570              * continue on without it.
0571              */
0572             dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
0573             htcpld->int_reset_gpio_hi = 0;
0574         } else {
0575             htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi;
0576             gpio_set_value(htcpld->int_reset_gpio_hi, 1);
0577         }
0578     }
0579 
0580     if (pdata->int_reset_gpio_lo) {
0581         ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core");
0582         if (ret) {
0583             /*
0584              * If it failed, that sucks, but we can probably
0585              * continue on without it.
0586              */
0587             dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
0588             htcpld->int_reset_gpio_lo = 0;
0589         } else {
0590             htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo;
0591             gpio_set_value(htcpld->int_reset_gpio_lo, 0);
0592         }
0593     }
0594 
0595     dev_info(dev, "Initialized successfully\n");
0596     return 0;
0597 }
0598 
0599 /* The I2C Driver -- used internally */
0600 static const struct i2c_device_id htcpld_chip_id[] = {
0601     { "htcpld-chip", 0 },
0602     { }
0603 };
0604 
0605 static struct i2c_driver htcpld_chip_driver = {
0606     .driver = {
0607         .name   = "htcpld-chip",
0608     },
0609     .id_table = htcpld_chip_id,
0610 };
0611 
0612 /* The Core Driver */
0613 static struct platform_driver htcpld_core_driver = {
0614     .driver = {
0615         .name = "i2c-htcpld",
0616     },
0617 };
0618 
0619 static int __init htcpld_core_init(void)
0620 {
0621     int ret;
0622 
0623     /* Register the I2C Chip driver */
0624     ret = i2c_add_driver(&htcpld_chip_driver);
0625     if (ret)
0626         return ret;
0627 
0628     /* Probe for our chips */
0629     return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
0630 }
0631 device_initcall(htcpld_core_init);