2 * Copyright (C) 2015 Samsung Electronics
3 * Przemyslaw Marczak <p.marczak@samsung.com>
5 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/arch/adc.h>
13 struct exynos_adc_priv
{
15 struct exynos_adc_v2
*regs
;
18 int exynos_adc_channel_data(struct udevice
*dev
, int channel
,
21 struct exynos_adc_priv
*priv
= dev_get_priv(dev
);
22 struct exynos_adc_v2
*regs
= priv
->regs
;
24 if (channel
!= priv
->active_channel
) {
25 error("Requested channel is not active!");
29 if (ADC_V2_GET_STATUS_FLAG(readl(®s
->status
)) != FLAG_CONV_END
)
32 *data
= readl(®s
->dat
) & ADC_V2_DAT_MASK
;
37 int exynos_adc_start_channel(struct udevice
*dev
, int channel
)
39 struct exynos_adc_priv
*priv
= dev_get_priv(dev
);
40 struct exynos_adc_v2
*regs
= priv
->regs
;
44 cfg
= readl(®s
->con2
);
45 cfg
&= ~ADC_V2_CON2_CHAN_SEL_MASK
;
46 cfg
|= ADC_V2_CON2_CHAN_SEL(channel
);
47 writel(cfg
, ®s
->con2
);
49 /* Start conversion */
50 cfg
= readl(®s
->con1
);
51 writel(cfg
| ADC_V2_CON1_STC_EN
, ®s
->con1
);
53 priv
->active_channel
= channel
;
58 int exynos_adc_stop(struct udevice
*dev
)
60 struct exynos_adc_priv
*priv
= dev_get_priv(dev
);
61 struct exynos_adc_v2
*regs
= priv
->regs
;
65 cfg
= readl(®s
->con1
);
66 cfg
|= ~ADC_V2_CON1_STC_EN
;
68 writel(cfg
, ®s
->con1
);
70 priv
->active_channel
= -1;
75 int exynos_adc_probe(struct udevice
*dev
)
77 struct exynos_adc_priv
*priv
= dev_get_priv(dev
);
78 struct exynos_adc_v2
*regs
= priv
->regs
;
81 /* Check HW version */
82 if (readl(®s
->version
) != ADC_V2_VERSION
) {
83 error("This driver supports only ADC v2!");
88 writel(ADC_V2_CON1_SOFT_RESET
, ®s
->con1
);
90 /* Disable INT - will read status only */
91 writel(0x0, ®s
->int_en
);
93 /* CON2 - set conversion parameters */
94 cfg
= ADC_V2_CON2_C_TIME(3); /* Conversion times: (1 << 3) = 8 */
95 cfg
|= ADC_V2_CON2_OSEL(OSEL_BINARY
);
96 cfg
|= ADC_V2_CON2_ESEL(ESEL_ADC_EVAL_TIME_20CLK
);
97 cfg
|= ADC_V2_CON2_HIGHF(HIGHF_CONV_RATE_600KSPS
);
98 writel(cfg
, ®s
->con2
);
100 priv
->active_channel
= -1;
105 int exynos_adc_ofdata_to_platdata(struct udevice
*dev
)
107 struct adc_uclass_platdata
*uc_pdata
= dev_get_uclass_platdata(dev
);
108 struct exynos_adc_priv
*priv
= dev_get_priv(dev
);
110 priv
->regs
= (struct exynos_adc_v2
*)dev_get_addr(dev
);
111 if (priv
->regs
== (struct exynos_adc_v2
*)FDT_ADDR_T_NONE
) {
112 error("Dev: %s - can't get address!", dev
->name
);
116 uc_pdata
->data_mask
= ADC_V2_DAT_MASK
;
117 uc_pdata
->data_format
= ADC_DATA_FORMAT_BIN
;
118 uc_pdata
->data_timeout_us
= ADC_V2_CONV_TIMEOUT_US
;
120 /* Mask available channel bits: [0:9] */
121 uc_pdata
->channel_mask
= (2 << ADC_V2_MAX_CHANNEL
) - 1;
126 static const struct adc_ops exynos_adc_ops
= {
127 .start_channel
= exynos_adc_start_channel
,
128 .channel_data
= exynos_adc_channel_data
,
129 .stop
= exynos_adc_stop
,
132 static const struct udevice_id exynos_adc_ids
[] = {
133 { .compatible
= "samsung,exynos-adc-v2" },
137 U_BOOT_DRIVER(exynos_adc
) = {
138 .name
= "exynos-adc",
140 .of_match
= exynos_adc_ids
,
141 .ops
= &exynos_adc_ops
,
142 .probe
= exynos_adc_probe
,
143 .ofdata_to_platdata
= exynos_adc_ofdata_to_platdata
,
144 .priv_auto_alloc_size
= sizeof(struct exynos_adc_priv
),