1 /* 2 * TI Touch Screen / ADC MFD driver 3 * 4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation version 2. 9 * 10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any 11 * kind, whether express or implied; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16 #include <linux/module.h> 17 #include <linux/slab.h> 18 #include <linux/err.h> 19 #include <linux/io.h> 20 #include <linux/clk.h> 21 #include <linux/regmap.h> 22 #include <linux/mfd/core.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/of.h> 25 #include <linux/of_device.h> 26 #include <linux/sched.h> 27 28 #include <linux/mfd/ti_am335x_tscadc.h> 29 30 static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg) 31 { 32 unsigned int val; 33 34 regmap_read(tsadc->regmap_tscadc, reg, &val); 35 return val; 36 } 37 38 static void tscadc_writel(struct ti_tscadc_dev *tsadc, unsigned int reg, 39 unsigned int val) 40 { 41 regmap_write(tsadc->regmap_tscadc, reg, val); 42 } 43 44 static const struct regmap_config tscadc_regmap_config = { 45 .name = "ti_tscadc", 46 .reg_bits = 32, 47 .reg_stride = 4, 48 .val_bits = 32, 49 }; 50 51 void am335x_tsc_se_set_cache(struct ti_tscadc_dev *tsadc, u32 val) 52 { 53 unsigned long flags; 54 55 spin_lock_irqsave(&tsadc->reg_lock, flags); 56 tsadc->reg_se_cache = val; 57 if (tsadc->adc_waiting) 58 wake_up(&tsadc->reg_se_wait); 59 else if (!tsadc->adc_in_use) 60 tscadc_writel(tsadc, REG_SE, val); 61 62 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 63 } 64 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_cache); 65 66 static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc) 67 { 68 DEFINE_WAIT(wait); 69 u32 reg; 70 71 /* 72 * disable TSC steps so it does not run while the ADC is using it. If 73 * write 0 while it is running (it just started or was already running) 74 * then it completes all steps that were enabled and stops then. 75 */ 76 tscadc_writel(tsadc, REG_SE, 0); 77 reg = tscadc_readl(tsadc, REG_ADCFSM); 78 if (reg & SEQ_STATUS) { 79 tsadc->adc_waiting = true; 80 prepare_to_wait(&tsadc->reg_se_wait, &wait, 81 TASK_UNINTERRUPTIBLE); 82 spin_unlock_irq(&tsadc->reg_lock); 83 84 schedule(); 85 86 spin_lock_irq(&tsadc->reg_lock); 87 finish_wait(&tsadc->reg_se_wait, &wait); 88 89 reg = tscadc_readl(tsadc, REG_ADCFSM); 90 WARN_ON(reg & SEQ_STATUS); 91 tsadc->adc_waiting = false; 92 } 93 tsadc->adc_in_use = true; 94 } 95 96 void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val) 97 { 98 spin_lock_irq(&tsadc->reg_lock); 99 am335x_tscadc_need_adc(tsadc); 100 101 tscadc_writel(tsadc, REG_SE, val); 102 spin_unlock_irq(&tsadc->reg_lock); 103 } 104 EXPORT_SYMBOL_GPL(am335x_tsc_se_set_once); 105 106 void am335x_tsc_se_adc_done(struct ti_tscadc_dev *tsadc) 107 { 108 unsigned long flags; 109 110 spin_lock_irqsave(&tsadc->reg_lock, flags); 111 tsadc->adc_in_use = false; 112 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache); 113 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 114 } 115 EXPORT_SYMBOL_GPL(am335x_tsc_se_adc_done); 116 117 void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val) 118 { 119 unsigned long flags; 120 121 spin_lock_irqsave(&tsadc->reg_lock, flags); 122 tsadc->reg_se_cache &= ~val; 123 tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache); 124 spin_unlock_irqrestore(&tsadc->reg_lock, flags); 125 } 126 EXPORT_SYMBOL_GPL(am335x_tsc_se_clr); 127 128 static void tscadc_idle_config(struct ti_tscadc_dev *config) 129 { 130 unsigned int idleconfig; 131 132 idleconfig = STEPCONFIG_YNN | STEPCONFIG_INM_ADCREFM | 133 STEPCONFIG_INP_ADCREFM | STEPCONFIG_YPN; 134 135 tscadc_writel(config, REG_IDLECONFIG, idleconfig); 136 } 137 138 static int ti_tscadc_probe(struct platform_device *pdev) 139 { 140 struct ti_tscadc_dev *tscadc; 141 struct resource *res; 142 struct clk *clk; 143 struct device_node *node = pdev->dev.of_node; 144 struct mfd_cell *cell; 145 struct property *prop; 146 const __be32 *cur; 147 u32 val; 148 int err, ctrl; 149 int clock_rate; 150 int tsc_wires = 0, adc_channels = 0, total_channels; 151 int readouts = 0; 152 153 if (!pdev->dev.of_node) { 154 dev_err(&pdev->dev, "Could not find valid DT data.\n"); 155 return -EINVAL; 156 } 157 158 node = of_get_child_by_name(pdev->dev.of_node, "tsc"); 159 of_property_read_u32(node, "ti,wires", &tsc_wires); 160 of_property_read_u32(node, "ti,coordiante-readouts", &readouts); 161 162 node = of_get_child_by_name(pdev->dev.of_node, "adc"); 163 of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { 164 adc_channels++; 165 if (val > 7) { 166 dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n", 167 val); 168 return -EINVAL; 169 } 170 } 171 total_channels = tsc_wires + adc_channels; 172 if (total_channels > 8) { 173 dev_err(&pdev->dev, "Number of i/p channels more than 8\n"); 174 return -EINVAL; 175 } 176 if (total_channels == 0) { 177 dev_err(&pdev->dev, "Need atleast one channel.\n"); 178 return -EINVAL; 179 } 180 181 if (readouts * 2 + 2 + adc_channels > 16) { 182 dev_err(&pdev->dev, "Too many step configurations requested\n"); 183 return -EINVAL; 184 } 185 186 /* Allocate memory for device */ 187 tscadc = devm_kzalloc(&pdev->dev, 188 sizeof(struct ti_tscadc_dev), GFP_KERNEL); 189 if (!tscadc) { 190 dev_err(&pdev->dev, "failed to allocate memory.\n"); 191 return -ENOMEM; 192 } 193 tscadc->dev = &pdev->dev; 194 195 err = platform_get_irq(pdev, 0); 196 if (err < 0) { 197 dev_err(&pdev->dev, "no irq ID is specified.\n"); 198 goto ret; 199 } else 200 tscadc->irq = err; 201 202 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 203 tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res); 204 if (IS_ERR(tscadc->tscadc_base)) 205 return PTR_ERR(tscadc->tscadc_base); 206 207 tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev, 208 tscadc->tscadc_base, &tscadc_regmap_config); 209 if (IS_ERR(tscadc->regmap_tscadc)) { 210 dev_err(&pdev->dev, "regmap init failed\n"); 211 err = PTR_ERR(tscadc->regmap_tscadc); 212 goto ret; 213 } 214 215 spin_lock_init(&tscadc->reg_lock); 216 init_waitqueue_head(&tscadc->reg_se_wait); 217 218 pm_runtime_enable(&pdev->dev); 219 pm_runtime_get_sync(&pdev->dev); 220 221 /* 222 * The TSC_ADC_Subsystem has 2 clock domains 223 * OCP_CLK and ADC_CLK. 224 * The ADC clock is expected to run at target of 3MHz, 225 * and expected to capture 12-bit data at a rate of 200 KSPS. 226 * The TSC_ADC_SS controller design assumes the OCP clock is 227 * at least 6x faster than the ADC clock. 228 */ 229 clk = clk_get(&pdev->dev, "adc_tsc_fck"); 230 if (IS_ERR(clk)) { 231 dev_err(&pdev->dev, "failed to get TSC fck\n"); 232 err = PTR_ERR(clk); 233 goto err_disable_clk; 234 } 235 clock_rate = clk_get_rate(clk); 236 clk_put(clk); 237 tscadc->clk_div = clock_rate / ADC_CLK; 238 239 /* TSCADC_CLKDIV needs to be configured to the value minus 1 */ 240 tscadc->clk_div--; 241 tscadc_writel(tscadc, REG_CLKDIV, tscadc->clk_div); 242 243 /* Set the control register bits */ 244 ctrl = CNTRLREG_STEPCONFIGWRT | 245 CNTRLREG_STEPID; 246 if (tsc_wires > 0) 247 ctrl |= CNTRLREG_4WIRE | CNTRLREG_TSCENB; 248 tscadc_writel(tscadc, REG_CTRL, ctrl); 249 250 /* Set register bits for Idle Config Mode */ 251 if (tsc_wires > 0) 252 tscadc_idle_config(tscadc); 253 254 /* Enable the TSC module enable bit */ 255 ctrl = tscadc_readl(tscadc, REG_CTRL); 256 ctrl |= CNTRLREG_TSCSSENB; 257 tscadc_writel(tscadc, REG_CTRL, ctrl); 258 259 tscadc->used_cells = 0; 260 tscadc->tsc_cell = -1; 261 tscadc->adc_cell = -1; 262 263 /* TSC Cell */ 264 if (tsc_wires > 0) { 265 tscadc->tsc_cell = tscadc->used_cells; 266 cell = &tscadc->cells[tscadc->used_cells++]; 267 cell->name = "TI-am335x-tsc"; 268 cell->of_compatible = "ti,am3359-tsc"; 269 cell->platform_data = &tscadc; 270 cell->pdata_size = sizeof(tscadc); 271 } 272 273 /* ADC Cell */ 274 if (adc_channels > 0) { 275 tscadc->adc_cell = tscadc->used_cells; 276 cell = &tscadc->cells[tscadc->used_cells++]; 277 cell->name = "TI-am335x-adc"; 278 cell->of_compatible = "ti,am3359-adc"; 279 cell->platform_data = &tscadc; 280 cell->pdata_size = sizeof(tscadc); 281 } 282 283 err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells, 284 tscadc->used_cells, NULL, 0, NULL); 285 if (err < 0) 286 goto err_disable_clk; 287 288 device_init_wakeup(&pdev->dev, true); 289 platform_set_drvdata(pdev, tscadc); 290 return 0; 291 292 err_disable_clk: 293 pm_runtime_put_sync(&pdev->dev); 294 pm_runtime_disable(&pdev->dev); 295 ret: 296 return err; 297 } 298 299 static int ti_tscadc_remove(struct platform_device *pdev) 300 { 301 struct ti_tscadc_dev *tscadc = platform_get_drvdata(pdev); 302 303 tscadc_writel(tscadc, REG_SE, 0x00); 304 305 pm_runtime_put_sync(&pdev->dev); 306 pm_runtime_disable(&pdev->dev); 307 308 mfd_remove_devices(tscadc->dev); 309 310 return 0; 311 } 312 313 #ifdef CONFIG_PM 314 static int tscadc_suspend(struct device *dev) 315 { 316 struct ti_tscadc_dev *tscadc_dev = dev_get_drvdata(dev); 317 318 tscadc_writel(tscadc_dev, REG_SE, 0x00); 319 pm_runtime_put_sync(dev); 320 321 return 0; 322 } 323 324 static int tscadc_resume(struct device *dev) 325 { 326 struct ti_tscadc_dev *tscadc_dev = dev_get_drvdata(dev); 327 unsigned int restore, ctrl; 328 329 pm_runtime_get_sync(dev); 330 331 /* context restore */ 332 ctrl = CNTRLREG_STEPCONFIGWRT | CNTRLREG_STEPID; 333 if (tscadc_dev->tsc_cell != -1) 334 ctrl |= CNTRLREG_TSCENB | CNTRLREG_4WIRE; 335 tscadc_writel(tscadc_dev, REG_CTRL, ctrl); 336 337 if (tscadc_dev->tsc_cell != -1) 338 tscadc_idle_config(tscadc_dev); 339 restore = tscadc_readl(tscadc_dev, REG_CTRL); 340 tscadc_writel(tscadc_dev, REG_CTRL, 341 (restore | CNTRLREG_TSCSSENB)); 342 343 tscadc_writel(tscadc_dev, REG_CLKDIV, tscadc_dev->clk_div); 344 345 return 0; 346 } 347 348 static const struct dev_pm_ops tscadc_pm_ops = { 349 .suspend = tscadc_suspend, 350 .resume = tscadc_resume, 351 }; 352 #define TSCADC_PM_OPS (&tscadc_pm_ops) 353 #else 354 #define TSCADC_PM_OPS NULL 355 #endif 356 357 static const struct of_device_id ti_tscadc_dt_ids[] = { 358 { .compatible = "ti,am3359-tscadc", }, 359 { } 360 }; 361 MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids); 362 363 static struct platform_driver ti_tscadc_driver = { 364 .driver = { 365 .name = "ti_am3359-tscadc", 366 .owner = THIS_MODULE, 367 .pm = TSCADC_PM_OPS, 368 .of_match_table = ti_tscadc_dt_ids, 369 }, 370 .probe = ti_tscadc_probe, 371 .remove = ti_tscadc_remove, 372 373 }; 374 375 module_platform_driver(ti_tscadc_driver); 376 377 MODULE_DESCRIPTION("TI touchscreen / ADC MFD controller driver"); 378 MODULE_AUTHOR("Rachna Patil <rachna@ti.com>"); 379 MODULE_LICENSE("GPL"); 380