Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * TI Touch Screen / ADC MFD driver
0004  *
0005  * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <linux/err.h>
0011 #include <linux/io.h>
0012 #include <linux/clk.h>
0013 #include <linux/regmap.h>
0014 #include <linux/mfd/core.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/of.h>
0017 #include <linux/of_device.h>
0018 #include <linux/sched.h>
0019 
0020 #include <linux/mfd/ti_am335x_tscadc.h>
0021 
0022 static const struct regmap_config tscadc_regmap_config = {
0023     .name = "ti_tscadc",
0024     .reg_bits = 32,
0025     .reg_stride = 4,
0026     .val_bits = 32,
0027 };
0028 
0029 void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tscadc, u32 val)
0030 {
0031     unsigned long flags;
0032 
0033     spin_lock_irqsave(&tscadc->reg_lock, flags);
0034     tscadc->reg_se_cache |= val;
0035     if (tscadc->adc_waiting)
0036         wake_up(&tscadc->reg_se_wait);
0037     else if (!tscadc->adc_in_use)
0038         regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
0039 
0040     spin_unlock_irqrestore(&tscadc->reg_lock, flags);
0041 }
0042 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache);
0043 
0044 static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tscadc)
0045 {
0046     DEFINE_WAIT(wait);
0047     u32 reg;
0048 
0049     regmap_read(tscadc->regmap, REG_ADCFSM, &reg);
0050     if (reg & SEQ_STATUS) {
0051         tscadc->adc_waiting = true;
0052         prepare_to_wait(&tscadc->reg_se_wait, &wait,
0053                 TASK_UNINTERRUPTIBLE);
0054         spin_unlock_irq(&tscadc->reg_lock);
0055 
0056         schedule();
0057 
0058         spin_lock_irq(&tscadc->reg_lock);
0059         finish_wait(&tscadc->reg_se_wait, &wait);
0060 
0061         /*
0062          * Sequencer should either be idle or
0063          * busy applying the charge step.
0064          */
0065         regmap_read(tscadc->regmap, REG_ADCFSM, &reg);
0066         WARN_ON((reg & SEQ_STATUS) && !(reg & CHARGE_STEP));
0067         tscadc->adc_waiting = false;
0068     }
0069     tscadc->adc_in_use = true;
0070 }
0071 
0072 void am335x_tsc_se_set_once(struct ti_tscadc_dev *tscadc, u32 val)
0073 {
0074     spin_lock_irq(&tscadc->reg_lock);
0075     am335x_tscadc_need_adc(tscadc);
0076 
0077     regmap_write(tscadc->regmap, REG_SE, val);
0078     spin_unlock_irq(&tscadc->reg_lock);
0079 }
0080 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once);
0081 
0082 void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tscadc)
0083 {
0084     unsigned long flags;
0085 
0086     spin_lock_irqsave(&tscadc->reg_lock, flags);
0087     tscadc->adc_in_use = false;
0088     regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
0089     spin_unlock_irqrestore(&tscadc->reg_lock, flags);
0090 }
0091 EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done);
0092 
0093 void am335x_tsc_se_clr(struct ti_tscadc_dev *tscadc, u32 val)
0094 {
0095     unsigned long flags;
0096 
0097     spin_lock_irqsave(&tscadc->reg_lock, flags);
0098     tscadc->reg_se_cache &= ~val;
0099     regmap_write(tscadc->regmap, REG_SE, tscadc->reg_se_cache);
0100     spin_unlock_irqrestore(&tscadc->reg_lock, flags);
0101 }
0102 EXPORT_SYMBOL_GPL(am335x_tsc_se_clr);
0103 
0104 static void tscadc_idle_config(struct ti_tscadc_dev *tscadc)
0105 {
0106     unsigned int idleconfig;
0107 
0108     idleconfig = STEPCONFIG_INM_ADCREFM | STEPCONFIG_INP_ADCREFM;
0109     if (ti_adc_with_touchscreen(tscadc))
0110         idleconfig |= STEPCONFIG_YNN | STEPCONFIG_YPN;
0111 
0112     regmap_write(tscadc->regmap, REG_IDLECONFIG, idleconfig);
0113 }
0114 
0115 static  int ti_tscadc_probe(struct platform_device *pdev)
0116 {
0117     struct ti_tscadc_dev *tscadc;
0118     struct resource *res;
0119     struct clk *clk;
0120     struct device_node *node;
0121     struct mfd_cell *cell;
0122     struct property *prop;
0123     const __be32 *cur;
0124     bool use_tsc = false, use_mag = false;
0125     u32 val;
0126     int err;
0127     int tscmag_wires = 0, adc_channels = 0, cell_idx = 0, total_channels;
0128     int readouts = 0, mag_tracks = 0;
0129 
0130     /* Allocate memory for device */
0131     tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
0132     if (!tscadc)
0133         return -ENOMEM;
0134 
0135     tscadc->dev = &pdev->dev;
0136 
0137     if (!pdev->dev.of_node) {
0138         dev_err(&pdev->dev, "Could not find valid DT data.\n");
0139         return -EINVAL;
0140     }
0141 
0142     tscadc->data = of_device_get_match_data(&pdev->dev);
0143 
0144     if (ti_adc_with_touchscreen(tscadc)) {
0145         node = of_get_child_by_name(pdev->dev.of_node, "tsc");
0146         of_property_read_u32(node, "ti,wires", &tscmag_wires);
0147         err = of_property_read_u32(node, "ti,coordinate-readouts",
0148                        &readouts);
0149         if (err < 0)
0150             of_property_read_u32(node, "ti,coordiante-readouts",
0151                          &readouts);
0152 
0153         of_node_put(node);
0154 
0155         if (tscmag_wires)
0156             use_tsc = true;
0157     } else {
0158         /*
0159          * When adding support for the magnetic stripe reader, here is
0160          * the place to look for the number of tracks used from device
0161          * tree. Let's default to 0 for now.
0162          */
0163         mag_tracks = 0;
0164         tscmag_wires = mag_tracks * 2;
0165         if (tscmag_wires)
0166             use_mag = true;
0167     }
0168 
0169     node = of_get_child_by_name(pdev->dev.of_node, "adc");
0170     of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
0171         adc_channels++;
0172         if (val > 7) {
0173             dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
0174                 val);
0175             of_node_put(node);
0176             return -EINVAL;
0177         }
0178     }
0179 
0180     of_node_put(node);
0181 
0182     total_channels = tscmag_wires + adc_channels;
0183     if (total_channels > 8) {
0184         dev_err(&pdev->dev, "Number of i/p channels more than 8\n");
0185         return -EINVAL;
0186     }
0187 
0188     if (total_channels == 0) {
0189         dev_err(&pdev->dev, "Need at least one channel.\n");
0190         return -EINVAL;
0191     }
0192 
0193     if (use_tsc && (readouts * 2 + 2 + adc_channels > 16)) {
0194         dev_err(&pdev->dev, "Too many step configurations requested\n");
0195         return -EINVAL;
0196     }
0197 
0198     err = platform_get_irq(pdev, 0);
0199     if (err < 0)
0200         return err;
0201     else
0202         tscadc->irq = err;
0203 
0204     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0205     tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
0206     if (IS_ERR(tscadc->tscadc_base))
0207         return PTR_ERR(tscadc->tscadc_base);
0208 
0209     tscadc->tscadc_phys_base = res->start;
0210     tscadc->regmap = devm_regmap_init_mmio(&pdev->dev,
0211                            tscadc->tscadc_base,
0212                            &tscadc_regmap_config);
0213     if (IS_ERR(tscadc->regmap)) {
0214         dev_err(&pdev->dev, "regmap init failed\n");
0215         return PTR_ERR(tscadc->regmap);
0216     }
0217 
0218     spin_lock_init(&tscadc->reg_lock);
0219     init_waitqueue_head(&tscadc->reg_se_wait);
0220 
0221     pm_runtime_enable(&pdev->dev);
0222     pm_runtime_get_sync(&pdev->dev);
0223 
0224     /*
0225      * The TSC_ADC_Subsystem has 2 clock domains: OCP_CLK and ADC_CLK.
0226      * ADCs produce a 12-bit sample every 15 ADC_CLK cycles.
0227      * am33xx ADCs expect to capture 200ksps.
0228      * am47xx ADCs expect to capture 867ksps.
0229      * We need ADC clocks respectively running at 3MHz and 13MHz.
0230      * These frequencies are valid since TSC_ADC_SS controller design
0231      * assumes the OCP clock is at least 6x faster than the ADC clock.
0232      */
0233     clk = devm_clk_get(&pdev->dev, NULL);
0234     if (IS_ERR(clk)) {
0235         dev_err(&pdev->dev, "failed to get fck\n");
0236         err = PTR_ERR(clk);
0237         goto err_disable_clk;
0238     }
0239 
0240     tscadc->clk_div = (clk_get_rate(clk) / tscadc->data->target_clk_rate) - 1;
0241     regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
0242 
0243     /*
0244      * Set the control register bits. tscadc->ctrl stores the configuration
0245      * of the CTRL register but not the subsystem enable bit which must be
0246      * added manually when timely.
0247      */
0248     tscadc->ctrl = CNTRLREG_STEPID;
0249     if (ti_adc_with_touchscreen(tscadc)) {
0250         tscadc->ctrl |= CNTRLREG_TSC_STEPCONFIGWRT;
0251         if (use_tsc) {
0252             tscadc->ctrl |= CNTRLREG_TSC_ENB;
0253             if (tscmag_wires == 5)
0254                 tscadc->ctrl |= CNTRLREG_TSC_5WIRE;
0255             else
0256                 tscadc->ctrl |= CNTRLREG_TSC_4WIRE;
0257         }
0258     } else {
0259         tscadc->ctrl |= CNTRLREG_MAG_PREAMP_PWRDOWN |
0260                 CNTRLREG_MAG_PREAMP_BYPASS;
0261     }
0262     regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl);
0263 
0264     tscadc_idle_config(tscadc);
0265 
0266     /* Enable the TSC module enable bit */
0267     regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl | CNTRLREG_SSENB);
0268 
0269     /* TSC or MAG Cell */
0270     if (use_tsc || use_mag) {
0271         cell = &tscadc->cells[cell_idx++];
0272         cell->name = tscadc->data->secondary_feature_name;
0273         cell->of_compatible = tscadc->data->secondary_feature_compatible;
0274         cell->platform_data = &tscadc;
0275         cell->pdata_size = sizeof(tscadc);
0276     }
0277 
0278     /* ADC Cell */
0279     if (adc_channels > 0) {
0280         cell = &tscadc->cells[cell_idx++];
0281         cell->name = tscadc->data->adc_feature_name;
0282         cell->of_compatible = tscadc->data->adc_feature_compatible;
0283         cell->platform_data = &tscadc;
0284         cell->pdata_size = sizeof(tscadc);
0285     }
0286 
0287     err = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
0288                   tscadc->cells, cell_idx, NULL, 0, NULL);
0289     if (err < 0)
0290         goto err_disable_clk;
0291 
0292     platform_set_drvdata(pdev, tscadc);
0293     return 0;
0294 
0295 err_disable_clk:
0296     pm_runtime_put_sync(&pdev->dev);
0297     pm_runtime_disable(&pdev->dev);
0298 
0299     return err;
0300 }
0301 
0302 static int ti_tscadc_remove(struct platform_device *pdev)
0303 {
0304     struct ti_tscadc_dev *tscadc = platform_get_drvdata(pdev);
0305 
0306     regmap_write(tscadc->regmap, REG_SE, 0x00);
0307 
0308     pm_runtime_put_sync(&pdev->dev);
0309     pm_runtime_disable(&pdev->dev);
0310 
0311     mfd_remove_devices(tscadc->dev);
0312 
0313     return 0;
0314 }
0315 
0316 static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data)
0317 {
0318     return device_may_wakeup(dev);
0319 }
0320 
0321 static int __maybe_unused tscadc_suspend(struct device *dev)
0322 {
0323     struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
0324 
0325     regmap_write(tscadc->regmap, REG_SE, 0x00);
0326     if (device_for_each_child(dev, NULL, ti_tscadc_can_wakeup)) {
0327         u32 ctrl;
0328 
0329         regmap_read(tscadc->regmap, REG_CTRL, &ctrl);
0330         ctrl &= ~(CNTRLREG_POWERDOWN);
0331         ctrl |= CNTRLREG_SSENB;
0332         regmap_write(tscadc->regmap, REG_CTRL, ctrl);
0333     }
0334     pm_runtime_put_sync(dev);
0335 
0336     return 0;
0337 }
0338 
0339 static int __maybe_unused tscadc_resume(struct device *dev)
0340 {
0341     struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
0342 
0343     pm_runtime_get_sync(dev);
0344 
0345     regmap_write(tscadc->regmap, REG_CLKDIV, tscadc->clk_div);
0346     regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl);
0347     tscadc_idle_config(tscadc);
0348     regmap_write(tscadc->regmap, REG_CTRL, tscadc->ctrl | CNTRLREG_SSENB);
0349 
0350     return 0;
0351 }
0352 
0353 static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
0354 
0355 static const struct ti_tscadc_data tscdata = {
0356     .adc_feature_name = "TI-am335x-adc",
0357     .adc_feature_compatible = "ti,am3359-adc",
0358     .secondary_feature_name = "TI-am335x-tsc",
0359     .secondary_feature_compatible = "ti,am3359-tsc",
0360     .target_clk_rate = TSC_ADC_CLK,
0361 };
0362 
0363 static const struct ti_tscadc_data magdata = {
0364     .adc_feature_name = "TI-am43xx-adc",
0365     .adc_feature_compatible = "ti,am4372-adc",
0366     .secondary_feature_name = "TI-am43xx-mag",
0367     .secondary_feature_compatible = "ti,am4372-mag",
0368     .target_clk_rate = MAG_ADC_CLK,
0369 };
0370 
0371 static const struct of_device_id ti_tscadc_dt_ids[] = {
0372     { .compatible = "ti,am3359-tscadc", .data = &tscdata },
0373     { .compatible = "ti,am4372-magadc", .data = &magdata },
0374     { }
0375 };
0376 MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
0377 
0378 static struct platform_driver ti_tscadc_driver = {
0379     .driver = {
0380         .name   = "ti_am3359-tscadc",
0381         .pm = &tscadc_pm_ops,
0382         .of_match_table = ti_tscadc_dt_ids,
0383     },
0384     .probe  = ti_tscadc_probe,
0385     .remove = ti_tscadc_remove,
0386 
0387 };
0388 
0389 module_platform_driver(ti_tscadc_driver);
0390 
0391 MODULE_DESCRIPTION("TI touchscreen/magnetic stripe reader/ADC MFD controller driver");
0392 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
0393 MODULE_LICENSE("GPL");