1024 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * exynos_adc.c - Support for ADC in EXYNOS SoCs4 *5 * 8 ~ 10 channel, 10/12-bit ADC6 *7 * Copyright (C) 2013 Naveen Krishna Chatradhi <ch.naveen@samsung.com>8 */9 10#include <linux/compiler.h>11#include <linux/module.h>12#include <linux/platform_device.h>13#include <linux/interrupt.h>14#include <linux/delay.h>15#include <linux/errno.h>16#include <linux/kernel.h>17#include <linux/slab.h>18#include <linux/io.h>19#include <linux/clk.h>20#include <linux/completion.h>21#include <linux/of.h>22#include <linux/of_irq.h>23#include <linux/regulator/consumer.h>24#include <linux/of_platform.h>25#include <linux/err.h>26#include <linux/input.h>27 28#include <linux/iio/iio.h>29#include <linux/iio/machine.h>30#include <linux/iio/driver.h>31#include <linux/mfd/syscon.h>32#include <linux/regmap.h>33 34#include <linux/platform_data/touchscreen-s3c2410.h>35 36/* S3C/EXYNOS4412/5250 ADC_V1 registers definitions */37#define ADC_V1_CON(x) ((x) + 0x00)38#define ADC_V1_TSC(x) ((x) + 0x04)39#define ADC_V1_DLY(x) ((x) + 0x08)40#define ADC_V1_DATX(x) ((x) + 0x0C)41#define ADC_V1_DATY(x) ((x) + 0x10)42#define ADC_V1_UPDN(x) ((x) + 0x14)43#define ADC_V1_INTCLR(x) ((x) + 0x18)44#define ADC_V1_MUX(x) ((x) + 0x1c)45#define ADC_V1_CLRINTPNDNUP(x) ((x) + 0x20)46 47/* S3C2410 ADC registers definitions */48#define ADC_S3C2410_MUX(x) ((x) + 0x18)49 50/* Future ADC_V2 registers definitions */51#define ADC_V2_CON1(x) ((x) + 0x00)52#define ADC_V2_CON2(x) ((x) + 0x04)53#define ADC_V2_STAT(x) ((x) + 0x08)54#define ADC_V2_INT_EN(x) ((x) + 0x10)55#define ADC_V2_INT_ST(x) ((x) + 0x14)56#define ADC_V2_VER(x) ((x) + 0x20)57 58/* Bit definitions for ADC_V1 */59#define ADC_V1_CON_RES (1u << 16)60#define ADC_V1_CON_PRSCEN (1u << 14)61#define ADC_V1_CON_PRSCLV(x) (((x) & 0xFF) << 6)62#define ADC_V1_CON_STANDBY (1u << 2)63 64/* Bit definitions for S3C2410 ADC */65#define ADC_S3C2410_CON_SELMUX(x) (((x) & 7) << 3)66#define ADC_S3C2410_DATX_MASK 0x3FF67#define ADC_S3C2416_CON_RES_SEL (1u << 3)68 69/* touch screen always uses channel 0 */70#define ADC_S3C2410_MUX_TS 071 72/* ADCTSC Register Bits */73#define ADC_S3C2443_TSC_UD_SEN (1u << 8)74#define ADC_S3C2410_TSC_YM_SEN (1u << 7)75#define ADC_S3C2410_TSC_YP_SEN (1u << 6)76#define ADC_S3C2410_TSC_XM_SEN (1u << 5)77#define ADC_S3C2410_TSC_XP_SEN (1u << 4)78#define ADC_S3C2410_TSC_PULL_UP_DISABLE (1u << 3)79#define ADC_S3C2410_TSC_AUTO_PST (1u << 2)80#define ADC_S3C2410_TSC_XY_PST(x) (((x) & 0x3) << 0)81 82#define ADC_TSC_WAIT4INT (ADC_S3C2410_TSC_YM_SEN | \83 ADC_S3C2410_TSC_YP_SEN | \84 ADC_S3C2410_TSC_XP_SEN | \85 ADC_S3C2410_TSC_XY_PST(3))86 87#define ADC_TSC_AUTOPST (ADC_S3C2410_TSC_YM_SEN | \88 ADC_S3C2410_TSC_YP_SEN | \89 ADC_S3C2410_TSC_XP_SEN | \90 ADC_S3C2410_TSC_AUTO_PST | \91 ADC_S3C2410_TSC_XY_PST(0))92 93/* Bit definitions for ADC_V2 */94#define ADC_V2_CON1_SOFT_RESET (1u << 2)95 96#define ADC_V2_CON2_OSEL (1u << 10)97#define ADC_V2_CON2_ESEL (1u << 9)98#define ADC_V2_CON2_HIGHF (1u << 8)99#define ADC_V2_CON2_C_TIME(x) (((x) & 7) << 4)100#define ADC_V2_CON2_ACH_SEL(x) (((x) & 0xF) << 0)101#define ADC_V2_CON2_ACH_MASK 0xF102 103#define MAX_ADC_V2_CHANNELS 10104#define MAX_ADC_V1_CHANNELS 8105#define MAX_EXYNOS3250_ADC_CHANNELS 2106#define MAX_EXYNOS4212_ADC_CHANNELS 4107#define MAX_S5PV210_ADC_CHANNELS 10108 109/* Bit definitions common for ADC_V1 and ADC_V2 */110#define ADC_CON_EN_START (1u << 0)111#define ADC_CON_EN_START_MASK (0x3 << 0)112#define ADC_DATX_PRESSED (1u << 15)113#define ADC_DATX_MASK 0xFFF114#define ADC_DATY_MASK 0xFFF115 116#define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100))117 118#define EXYNOS_ADCV1_PHY_OFFSET 0x0718119#define EXYNOS_ADCV2_PHY_OFFSET 0x0720120 121struct exynos_adc {122 struct exynos_adc_data *data;123 struct device *dev;124 struct input_dev *input;125 void __iomem *regs;126 struct regmap *pmu_map;127 struct clk *clk;128 struct clk *sclk;129 unsigned int irq;130 unsigned int tsirq;131 unsigned int delay;132 struct regulator *vdd;133 134 struct completion completion;135 136 u32 value;137 unsigned int version;138 139 bool ts_enabled;140 141 bool read_ts;142 u32 ts_x;143 u32 ts_y;144 145 /*146 * Lock to protect from potential concurrent access to the147 * completion callback during a manual conversion. For this driver148 * a wait-callback is used to wait for the conversion result,149 * so in the meantime no other read request (or conversion start)150 * must be performed, otherwise it would interfere with the151 * current conversion result.152 */153 struct mutex lock;154};155 156struct exynos_adc_data {157 int num_channels;158 bool needs_sclk;159 bool needs_adc_phy;160 int phy_offset;161 u32 mask;162 163 void (*init_hw)(struct exynos_adc *info);164 void (*exit_hw)(struct exynos_adc *info);165 void (*clear_irq)(struct exynos_adc *info);166 void (*start_conv)(struct exynos_adc *info, unsigned long addr);167};168 169static void exynos_adc_unprepare_clk(struct exynos_adc *info)170{171 if (info->data->needs_sclk)172 clk_unprepare(info->sclk);173 clk_unprepare(info->clk);174}175 176static int exynos_adc_prepare_clk(struct exynos_adc *info)177{178 int ret;179 180 ret = clk_prepare(info->clk);181 if (ret) {182 dev_err(info->dev, "failed preparing adc clock: %d\n", ret);183 return ret;184 }185 186 if (info->data->needs_sclk) {187 ret = clk_prepare(info->sclk);188 if (ret) {189 clk_unprepare(info->clk);190 dev_err(info->dev,191 "failed preparing sclk_adc clock: %d\n", ret);192 return ret;193 }194 }195 196 return 0;197}198 199static void exynos_adc_disable_clk(struct exynos_adc *info)200{201 if (info->data->needs_sclk)202 clk_disable(info->sclk);203 clk_disable(info->clk);204}205 206static int exynos_adc_enable_clk(struct exynos_adc *info)207{208 int ret;209 210 ret = clk_enable(info->clk);211 if (ret) {212 dev_err(info->dev, "failed enabling adc clock: %d\n", ret);213 return ret;214 }215 216 if (info->data->needs_sclk) {217 ret = clk_enable(info->sclk);218 if (ret) {219 clk_disable(info->clk);220 dev_err(info->dev,221 "failed enabling sclk_adc clock: %d\n", ret);222 return ret;223 }224 }225 226 return 0;227}228 229static void exynos_adc_v1_init_hw(struct exynos_adc *info)230{231 u32 con1;232 233 if (info->data->needs_adc_phy)234 regmap_write(info->pmu_map, info->data->phy_offset, 1);235 236 /* set default prescaler values and Enable prescaler */237 con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;238 239 /* Enable 12-bit ADC resolution */240 con1 |= ADC_V1_CON_RES;241 writel(con1, ADC_V1_CON(info->regs));242 243 /* set touchscreen delay */244 writel(info->delay, ADC_V1_DLY(info->regs));245}246 247static void exynos_adc_v1_exit_hw(struct exynos_adc *info)248{249 u32 con;250 251 if (info->data->needs_adc_phy)252 regmap_write(info->pmu_map, info->data->phy_offset, 0);253 254 con = readl(ADC_V1_CON(info->regs));255 con |= ADC_V1_CON_STANDBY;256 writel(con, ADC_V1_CON(info->regs));257}258 259static void exynos_adc_v1_clear_irq(struct exynos_adc *info)260{261 writel(1, ADC_V1_INTCLR(info->regs));262}263 264static void exynos_adc_v1_start_conv(struct exynos_adc *info,265 unsigned long addr)266{267 u32 con1;268 269 writel(addr, ADC_V1_MUX(info->regs));270 271 con1 = readl(ADC_V1_CON(info->regs));272 writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs));273}274 275/* Exynos4212 and 4412 is like ADCv1 but with four channels only */276static const struct exynos_adc_data exynos4212_adc_data = {277 .num_channels = MAX_EXYNOS4212_ADC_CHANNELS,278 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */279 .needs_adc_phy = true,280 .phy_offset = EXYNOS_ADCV1_PHY_OFFSET,281 282 .init_hw = exynos_adc_v1_init_hw,283 .exit_hw = exynos_adc_v1_exit_hw,284 .clear_irq = exynos_adc_v1_clear_irq,285 .start_conv = exynos_adc_v1_start_conv,286};287 288static const struct exynos_adc_data exynos_adc_v1_data = {289 .num_channels = MAX_ADC_V1_CHANNELS,290 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */291 .needs_adc_phy = true,292 .phy_offset = EXYNOS_ADCV1_PHY_OFFSET,293 294 .init_hw = exynos_adc_v1_init_hw,295 .exit_hw = exynos_adc_v1_exit_hw,296 .clear_irq = exynos_adc_v1_clear_irq,297 .start_conv = exynos_adc_v1_start_conv,298};299 300static const struct exynos_adc_data exynos_adc_s5pv210_data = {301 .num_channels = MAX_S5PV210_ADC_CHANNELS,302 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */303 304 .init_hw = exynos_adc_v1_init_hw,305 .exit_hw = exynos_adc_v1_exit_hw,306 .clear_irq = exynos_adc_v1_clear_irq,307 .start_conv = exynos_adc_v1_start_conv,308};309 310static void exynos_adc_s3c2416_start_conv(struct exynos_adc *info,311 unsigned long addr)312{313 u32 con1;314 315 /* Enable 12 bit ADC resolution */316 con1 = readl(ADC_V1_CON(info->regs));317 con1 |= ADC_S3C2416_CON_RES_SEL;318 writel(con1, ADC_V1_CON(info->regs));319 320 /* Select channel for S3C2416 */321 writel(addr, ADC_S3C2410_MUX(info->regs));322 323 con1 = readl(ADC_V1_CON(info->regs));324 writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs));325}326 327static struct exynos_adc_data const exynos_adc_s3c2416_data = {328 .num_channels = MAX_ADC_V1_CHANNELS,329 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */330 331 .init_hw = exynos_adc_v1_init_hw,332 .exit_hw = exynos_adc_v1_exit_hw,333 .start_conv = exynos_adc_s3c2416_start_conv,334};335 336static void exynos_adc_s3c2443_start_conv(struct exynos_adc *info,337 unsigned long addr)338{339 u32 con1;340 341 /* Select channel for S3C2433 */342 writel(addr, ADC_S3C2410_MUX(info->regs));343 344 con1 = readl(ADC_V1_CON(info->regs));345 writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs));346}347 348static struct exynos_adc_data const exynos_adc_s3c2443_data = {349 .num_channels = MAX_ADC_V1_CHANNELS,350 .mask = ADC_S3C2410_DATX_MASK, /* 10 bit ADC resolution */351 352 .init_hw = exynos_adc_v1_init_hw,353 .exit_hw = exynos_adc_v1_exit_hw,354 .start_conv = exynos_adc_s3c2443_start_conv,355};356 357static void exynos_adc_s3c64xx_start_conv(struct exynos_adc *info,358 unsigned long addr)359{360 u32 con1;361 362 con1 = readl(ADC_V1_CON(info->regs));363 con1 &= ~ADC_S3C2410_CON_SELMUX(0x7);364 con1 |= ADC_S3C2410_CON_SELMUX(addr);365 writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs));366}367 368static struct exynos_adc_data const exynos_adc_s3c24xx_data = {369 .num_channels = MAX_ADC_V1_CHANNELS,370 .mask = ADC_S3C2410_DATX_MASK, /* 10 bit ADC resolution */371 372 .init_hw = exynos_adc_v1_init_hw,373 .exit_hw = exynos_adc_v1_exit_hw,374 .start_conv = exynos_adc_s3c64xx_start_conv,375};376 377static struct exynos_adc_data const exynos_adc_s3c64xx_data = {378 .num_channels = MAX_ADC_V1_CHANNELS,379 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */380 381 .init_hw = exynos_adc_v1_init_hw,382 .exit_hw = exynos_adc_v1_exit_hw,383 .clear_irq = exynos_adc_v1_clear_irq,384 .start_conv = exynos_adc_s3c64xx_start_conv,385};386 387static void exynos_adc_v2_init_hw(struct exynos_adc *info)388{389 u32 con1, con2;390 391 if (info->data->needs_adc_phy)392 regmap_write(info->pmu_map, info->data->phy_offset, 1);393 394 con1 = ADC_V2_CON1_SOFT_RESET;395 writel(con1, ADC_V2_CON1(info->regs));396 397 con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |398 ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);399 writel(con2, ADC_V2_CON2(info->regs));400 401 /* Enable interrupts */402 writel(1, ADC_V2_INT_EN(info->regs));403}404 405static void exynos_adc_v2_exit_hw(struct exynos_adc *info)406{407 u32 con;408 409 if (info->data->needs_adc_phy)410 regmap_write(info->pmu_map, info->data->phy_offset, 0);411 412 con = readl(ADC_V2_CON1(info->regs));413 con &= ~ADC_CON_EN_START;414 writel(con, ADC_V2_CON1(info->regs));415}416 417static void exynos_adc_v2_clear_irq(struct exynos_adc *info)418{419 writel(1, ADC_V2_INT_ST(info->regs));420}421 422static void exynos_adc_v2_start_conv(struct exynos_adc *info,423 unsigned long addr)424{425 u32 con1, con2;426 427 con2 = readl(ADC_V2_CON2(info->regs));428 con2 &= ~ADC_V2_CON2_ACH_MASK;429 con2 |= ADC_V2_CON2_ACH_SEL(addr);430 writel(con2, ADC_V2_CON2(info->regs));431 432 con1 = readl(ADC_V2_CON1(info->regs));433 writel(con1 | ADC_CON_EN_START, ADC_V2_CON1(info->regs));434}435 436static const struct exynos_adc_data exynos_adc_v2_data = {437 .num_channels = MAX_ADC_V2_CHANNELS,438 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */439 .needs_adc_phy = true,440 .phy_offset = EXYNOS_ADCV2_PHY_OFFSET,441 442 .init_hw = exynos_adc_v2_init_hw,443 .exit_hw = exynos_adc_v2_exit_hw,444 .clear_irq = exynos_adc_v2_clear_irq,445 .start_conv = exynos_adc_v2_start_conv,446};447 448static const struct exynos_adc_data exynos3250_adc_data = {449 .num_channels = MAX_EXYNOS3250_ADC_CHANNELS,450 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */451 .needs_sclk = true,452 .needs_adc_phy = true,453 .phy_offset = EXYNOS_ADCV1_PHY_OFFSET,454 455 .init_hw = exynos_adc_v2_init_hw,456 .exit_hw = exynos_adc_v2_exit_hw,457 .clear_irq = exynos_adc_v2_clear_irq,458 .start_conv = exynos_adc_v2_start_conv,459};460 461static void exynos_adc_exynos7_init_hw(struct exynos_adc *info)462{463 u32 con1, con2;464 465 con1 = ADC_V2_CON1_SOFT_RESET;466 writel(con1, ADC_V2_CON1(info->regs));467 468 con2 = readl(ADC_V2_CON2(info->regs));469 con2 &= ~ADC_V2_CON2_C_TIME(7);470 con2 |= ADC_V2_CON2_C_TIME(0);471 writel(con2, ADC_V2_CON2(info->regs));472 473 /* Enable interrupts */474 writel(1, ADC_V2_INT_EN(info->regs));475}476 477static const struct exynos_adc_data exynos7_adc_data = {478 .num_channels = MAX_ADC_V1_CHANNELS,479 .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */480 481 .init_hw = exynos_adc_exynos7_init_hw,482 .exit_hw = exynos_adc_v2_exit_hw,483 .clear_irq = exynos_adc_v2_clear_irq,484 .start_conv = exynos_adc_v2_start_conv,485};486 487static const struct of_device_id exynos_adc_match[] = {488 {489 .compatible = "samsung,s3c2410-adc",490 .data = &exynos_adc_s3c24xx_data,491 }, {492 .compatible = "samsung,s3c2416-adc",493 .data = &exynos_adc_s3c2416_data,494 }, {495 .compatible = "samsung,s3c2440-adc",496 .data = &exynos_adc_s3c24xx_data,497 }, {498 .compatible = "samsung,s3c2443-adc",499 .data = &exynos_adc_s3c2443_data,500 }, {501 .compatible = "samsung,s3c6410-adc",502 .data = &exynos_adc_s3c64xx_data,503 }, {504 .compatible = "samsung,s5pv210-adc",505 .data = &exynos_adc_s5pv210_data,506 }, {507 .compatible = "samsung,exynos4212-adc",508 .data = &exynos4212_adc_data,509 }, {510 .compatible = "samsung,exynos-adc-v1",511 .data = &exynos_adc_v1_data,512 }, {513 .compatible = "samsung,exynos-adc-v2",514 .data = &exynos_adc_v2_data,515 }, {516 .compatible = "samsung,exynos3250-adc",517 .data = &exynos3250_adc_data,518 }, {519 .compatible = "samsung,exynos7-adc",520 .data = &exynos7_adc_data,521 },522 { }523};524MODULE_DEVICE_TABLE(of, exynos_adc_match);525 526static struct exynos_adc_data *exynos_adc_get_data(struct platform_device *pdev)527{528 const struct of_device_id *match;529 530 match = of_match_node(exynos_adc_match, pdev->dev.of_node);531 return (struct exynos_adc_data *)match->data;532}533 534static int exynos_read_raw(struct iio_dev *indio_dev,535 struct iio_chan_spec const *chan,536 int *val,537 int *val2,538 long mask)539{540 struct exynos_adc *info = iio_priv(indio_dev);541 unsigned long time_left;542 int ret;543 544 if (mask == IIO_CHAN_INFO_SCALE) {545 ret = regulator_get_voltage(info->vdd);546 if (ret < 0)547 return ret;548 549 /* Regulator voltage is in uV, but need mV */550 *val = ret / 1000;551 *val2 = info->data->mask;552 553 return IIO_VAL_FRACTIONAL;554 } else if (mask != IIO_CHAN_INFO_RAW) {555 return -EINVAL;556 }557 558 mutex_lock(&info->lock);559 reinit_completion(&info->completion);560 561 /* Select the channel to be used and Trigger conversion */562 if (info->data->start_conv)563 info->data->start_conv(info, chan->address);564 565 time_left = wait_for_completion_timeout(&info->completion,566 EXYNOS_ADC_TIMEOUT);567 if (time_left == 0) {568 dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");569 if (info->data->init_hw)570 info->data->init_hw(info);571 ret = -ETIMEDOUT;572 } else {573 *val = info->value;574 *val2 = 0;575 ret = IIO_VAL_INT;576 }577 578 mutex_unlock(&info->lock);579 580 return ret;581}582 583static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)584{585 struct exynos_adc *info = iio_priv(indio_dev);586 unsigned long time_left;587 int ret;588 589 mutex_lock(&info->lock);590 info->read_ts = true;591 592 reinit_completion(&info->completion);593 594 writel(ADC_S3C2410_TSC_PULL_UP_DISABLE | ADC_TSC_AUTOPST,595 ADC_V1_TSC(info->regs));596 597 /* Select the ts channel to be used and Trigger conversion */598 info->data->start_conv(info, ADC_S3C2410_MUX_TS);599 600 time_left = wait_for_completion_timeout(&info->completion,601 EXYNOS_ADC_TIMEOUT);602 if (time_left == 0) {603 dev_warn(&indio_dev->dev, "Conversion timed out! Resetting\n");604 if (info->data->init_hw)605 info->data->init_hw(info);606 ret = -ETIMEDOUT;607 } else {608 *x = info->ts_x;609 *y = info->ts_y;610 ret = 0;611 }612 613 info->read_ts = false;614 mutex_unlock(&info->lock);615 616 return ret;617}618 619static irqreturn_t exynos_adc_isr(int irq, void *dev_id)620{621 struct exynos_adc *info = dev_id;622 u32 mask = info->data->mask;623 624 /* Read value */625 if (info->read_ts) {626 info->ts_x = readl(ADC_V1_DATX(info->regs));627 info->ts_y = readl(ADC_V1_DATY(info->regs));628 writel(ADC_TSC_WAIT4INT | ADC_S3C2443_TSC_UD_SEN, ADC_V1_TSC(info->regs));629 } else {630 info->value = readl(ADC_V1_DATX(info->regs)) & mask;631 }632 633 /* clear irq */634 if (info->data->clear_irq)635 info->data->clear_irq(info);636 637 complete(&info->completion);638 639 return IRQ_HANDLED;640}641 642/*643 * Here we (ab)use a threaded interrupt handler to stay running644 * for as long as the touchscreen remains pressed, we report645 * a new event with the latest data and then sleep until the646 * next timer tick. This mirrors the behavior of the old647 * driver, with much less code.648 */649static irqreturn_t exynos_ts_isr(int irq, void *dev_id)650{651 struct exynos_adc *info = dev_id;652 struct iio_dev *dev = dev_get_drvdata(info->dev);653 u32 x, y;654 bool pressed;655 int ret;656 657 while (READ_ONCE(info->ts_enabled)) {658 ret = exynos_read_s3c64xx_ts(dev, &x, &y);659 if (ret == -ETIMEDOUT)660 break;661 662 pressed = x & y & ADC_DATX_PRESSED;663 if (!pressed) {664 input_report_key(info->input, BTN_TOUCH, 0);665 input_sync(info->input);666 break;667 }668 669 input_report_abs(info->input, ABS_X, x & ADC_DATX_MASK);670 input_report_abs(info->input, ABS_Y, y & ADC_DATY_MASK);671 input_report_key(info->input, BTN_TOUCH, 1);672 input_sync(info->input);673 674 usleep_range(1000, 1100);675 }676 677 writel(0, ADC_V1_CLRINTPNDNUP(info->regs));678 679 return IRQ_HANDLED;680}681 682static int exynos_adc_reg_access(struct iio_dev *indio_dev,683 unsigned reg, unsigned writeval,684 unsigned *readval)685{686 struct exynos_adc *info = iio_priv(indio_dev);687 688 if (readval == NULL)689 return -EINVAL;690 691 *readval = readl(info->regs + reg);692 693 return 0;694}695 696static const struct iio_info exynos_adc_iio_info = {697 .read_raw = &exynos_read_raw,698 .debugfs_reg_access = &exynos_adc_reg_access,699};700 701#define ADC_CHANNEL(_index, _id) { \702 .type = IIO_VOLTAGE, \703 .indexed = 1, \704 .channel = _index, \705 .address = _index, \706 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \707 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \708 .datasheet_name = _id, \709}710 711static const struct iio_chan_spec exynos_adc_iio_channels[] = {712 ADC_CHANNEL(0, "adc0"),713 ADC_CHANNEL(1, "adc1"),714 ADC_CHANNEL(2, "adc2"),715 ADC_CHANNEL(3, "adc3"),716 ADC_CHANNEL(4, "adc4"),717 ADC_CHANNEL(5, "adc5"),718 ADC_CHANNEL(6, "adc6"),719 ADC_CHANNEL(7, "adc7"),720 ADC_CHANNEL(8, "adc8"),721 ADC_CHANNEL(9, "adc9"),722};723 724static int exynos_adc_remove_devices(struct device *dev, void *c)725{726 struct platform_device *pdev = to_platform_device(dev);727 728 platform_device_unregister(pdev);729 730 return 0;731}732 733static int exynos_adc_ts_open(struct input_dev *dev)734{735 struct exynos_adc *info = input_get_drvdata(dev);736 737 WRITE_ONCE(info->ts_enabled, true);738 enable_irq(info->tsirq);739 740 return 0;741}742 743static void exynos_adc_ts_close(struct input_dev *dev)744{745 struct exynos_adc *info = input_get_drvdata(dev);746 747 WRITE_ONCE(info->ts_enabled, false);748 disable_irq(info->tsirq);749}750 751static int exynos_adc_ts_init(struct exynos_adc *info)752{753 int ret;754 755 if (info->tsirq <= 0)756 return -ENODEV;757 758 info->input = input_allocate_device();759 if (!info->input)760 return -ENOMEM;761 762 info->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);763 info->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);764 765 input_set_abs_params(info->input, ABS_X, 0, 0x3FF, 0, 0);766 input_set_abs_params(info->input, ABS_Y, 0, 0x3FF, 0, 0);767 768 info->input->name = "S3C24xx TouchScreen";769 info->input->id.bustype = BUS_HOST;770 info->input->open = exynos_adc_ts_open;771 info->input->close = exynos_adc_ts_close;772 773 input_set_drvdata(info->input, info);774 775 ret = input_register_device(info->input);776 if (ret) {777 input_free_device(info->input);778 return ret;779 }780 781 ret = request_threaded_irq(info->tsirq, NULL, exynos_ts_isr,782 IRQF_ONESHOT | IRQF_NO_AUTOEN,783 "touchscreen", info);784 if (ret)785 input_unregister_device(info->input);786 787 return ret;788}789 790static int exynos_adc_probe(struct platform_device *pdev)791{792 struct exynos_adc *info = NULL;793 struct device_node *np = pdev->dev.of_node;794 struct s3c2410_ts_mach_info *pdata = dev_get_platdata(&pdev->dev);795 struct iio_dev *indio_dev = NULL;796 bool has_ts = false;797 int ret;798 int irq;799 800 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc));801 if (!indio_dev) {802 dev_err(&pdev->dev, "failed allocating iio device\n");803 return -ENOMEM;804 }805 806 info = iio_priv(indio_dev);807 808 info->data = exynos_adc_get_data(pdev);809 if (!info->data) {810 dev_err(&pdev->dev, "failed getting exynos_adc_data\n");811 return -EINVAL;812 }813 814 info->regs = devm_platform_ioremap_resource(pdev, 0);815 if (IS_ERR(info->regs))816 return PTR_ERR(info->regs);817 818 819 if (info->data->needs_adc_phy) {820 info->pmu_map = syscon_regmap_lookup_by_phandle(821 pdev->dev.of_node,822 "samsung,syscon-phandle");823 if (IS_ERR(info->pmu_map)) {824 dev_err(&pdev->dev, "syscon regmap lookup failed.\n");825 return PTR_ERR(info->pmu_map);826 }827 }828 829 /* leave out any TS related code if unreachable */830 if (IS_REACHABLE(CONFIG_INPUT)) {831 has_ts = of_property_read_bool(pdev->dev.of_node,832 "has-touchscreen") || pdata;833 }834 835 irq = platform_get_irq(pdev, 0);836 if (irq < 0)837 return irq;838 info->irq = irq;839 840 if (has_ts) {841 irq = platform_get_irq(pdev, 1);842 if (irq == -EPROBE_DEFER)843 return irq;844 845 info->tsirq = irq;846 } else {847 info->tsirq = -1;848 }849 850 info->dev = &pdev->dev;851 852 init_completion(&info->completion);853 854 info->clk = devm_clk_get(&pdev->dev, "adc");855 if (IS_ERR(info->clk)) {856 dev_err(&pdev->dev, "failed getting clock, err = %ld\n",857 PTR_ERR(info->clk));858 return PTR_ERR(info->clk);859 }860 861 if (info->data->needs_sclk) {862 info->sclk = devm_clk_get(&pdev->dev, "sclk");863 if (IS_ERR(info->sclk)) {864 dev_err(&pdev->dev,865 "failed getting sclk clock, err = %ld\n",866 PTR_ERR(info->sclk));867 return PTR_ERR(info->sclk);868 }869 }870 871 info->vdd = devm_regulator_get(&pdev->dev, "vdd");872 if (IS_ERR(info->vdd))873 return dev_err_probe(&pdev->dev, PTR_ERR(info->vdd),874 "failed getting regulator");875 876 ret = regulator_enable(info->vdd);877 if (ret)878 return ret;879 880 ret = exynos_adc_prepare_clk(info);881 if (ret)882 goto err_disable_reg;883 884 ret = exynos_adc_enable_clk(info);885 if (ret)886 goto err_unprepare_clk;887 888 platform_set_drvdata(pdev, indio_dev);889 890 indio_dev->name = dev_name(&pdev->dev);891 indio_dev->info = &exynos_adc_iio_info;892 indio_dev->modes = INDIO_DIRECT_MODE;893 indio_dev->channels = exynos_adc_iio_channels;894 indio_dev->num_channels = info->data->num_channels;895 896 mutex_init(&info->lock);897 898 ret = request_irq(info->irq, exynos_adc_isr,899 0, dev_name(&pdev->dev), info);900 if (ret < 0) {901 dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",902 info->irq);903 goto err_disable_clk;904 }905 906 ret = iio_device_register(indio_dev);907 if (ret)908 goto err_irq;909 910 if (info->data->init_hw)911 info->data->init_hw(info);912 913 if (pdata)914 info->delay = pdata->delay;915 else916 info->delay = 10000;917 918 if (has_ts)919 ret = exynos_adc_ts_init(info);920 if (ret)921 goto err_iio;922 923 ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev);924 if (ret < 0) {925 dev_err(&pdev->dev, "failed adding child nodes\n");926 goto err_of_populate;927 }928 929 return 0;930 931err_of_populate:932 device_for_each_child(&indio_dev->dev, NULL,933 exynos_adc_remove_devices);934 if (has_ts) {935 input_unregister_device(info->input);936 free_irq(info->tsirq, info);937 }938err_iio:939 iio_device_unregister(indio_dev);940err_irq:941 free_irq(info->irq, info);942err_disable_clk:943 if (info->data->exit_hw)944 info->data->exit_hw(info);945 exynos_adc_disable_clk(info);946err_unprepare_clk:947 exynos_adc_unprepare_clk(info);948err_disable_reg:949 regulator_disable(info->vdd);950 return ret;951}952 953static void exynos_adc_remove(struct platform_device *pdev)954{955 struct iio_dev *indio_dev = platform_get_drvdata(pdev);956 struct exynos_adc *info = iio_priv(indio_dev);957 958 if (IS_REACHABLE(CONFIG_INPUT) && info->input) {959 free_irq(info->tsirq, info);960 input_unregister_device(info->input);961 }962 device_for_each_child(&indio_dev->dev, NULL,963 exynos_adc_remove_devices);964 iio_device_unregister(indio_dev);965 free_irq(info->irq, info);966 if (info->data->exit_hw)967 info->data->exit_hw(info);968 exynos_adc_disable_clk(info);969 exynos_adc_unprepare_clk(info);970 regulator_disable(info->vdd);971}972 973static int exynos_adc_suspend(struct device *dev)974{975 struct iio_dev *indio_dev = dev_get_drvdata(dev);976 struct exynos_adc *info = iio_priv(indio_dev);977 978 if (info->data->exit_hw)979 info->data->exit_hw(info);980 exynos_adc_disable_clk(info);981 regulator_disable(info->vdd);982 983 return 0;984}985 986static int exynos_adc_resume(struct device *dev)987{988 struct iio_dev *indio_dev = dev_get_drvdata(dev);989 struct exynos_adc *info = iio_priv(indio_dev);990 int ret;991 992 ret = regulator_enable(info->vdd);993 if (ret)994 return ret;995 996 ret = exynos_adc_enable_clk(info);997 if (ret)998 return ret;999 1000 if (info->data->init_hw)1001 info->data->init_hw(info);1002 1003 return 0;1004}1005 1006static DEFINE_SIMPLE_DEV_PM_OPS(exynos_adc_pm_ops, exynos_adc_suspend,1007 exynos_adc_resume);1008 1009static struct platform_driver exynos_adc_driver = {1010 .probe = exynos_adc_probe,1011 .remove_new = exynos_adc_remove,1012 .driver = {1013 .name = "exynos-adc",1014 .of_match_table = exynos_adc_match,1015 .pm = pm_sleep_ptr(&exynos_adc_pm_ops),1016 },1017};1018 1019module_platform_driver(exynos_adc_driver);1020 1021MODULE_AUTHOR("Naveen Krishna Chatradhi <ch.naveen@samsung.com>");1022MODULE_DESCRIPTION("Samsung EXYNOS5 ADC driver");1023MODULE_LICENSE("GPL v2");1024