public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Przemyslaw Marczak <p.marczak@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH V2 07/11] dm: adc: add Exynos54xx compatible ADC driver
Date: Tue, 13 Oct 2015 13:58:41 +0200	[thread overview]
Message-ID: <561CF1F1.4010801@samsung.com> (raw)
In-Reply-To: <CAPnjgZ0FczL7a5cBqpH+dqEj9Ur+vRKFdqJmNqyGwG5HLL91Pg@mail.gmail.com>

Hello Simon,

On 10/03/2015 04:28 PM, Simon Glass wrote:
> Hi Przemyslaw,
>
> On 21 September 2015 at 13:26, Przemyslaw Marczak <p.marczak@samsung.com> wrote:
>> This commit adds driver for Exynos54xx ADC subsystem.
>>
>> The driver is implemented using driver model,
>> amd provides ADC uclass's operations:
>> - adc_init()
>> - adc_data()
>>
>> This driver uses sdelay() function on pooling, so it can
>> be used before the delay timer is inited.
>> The basic parameters of ADC conversion, are:
>> - sample rate: 600KSPS
>> - output the data as average of 8 time conversion
>>
>> ADC features:
>> - sample rate: 600KSPS
>> - resolution: 12-bit
>> - channels: 10 (analog multiplexer)
>>
>> Signed-off-by: Przemyslaw Marczak <p.marczak@samsung.com>
>> ---
>> Changes V2:
>> - new commit - move previous adc driver from SoC directory to drivers/adc
>> ---
>>   arch/arm/mach-exynos/include/mach/adc.h |  45 ++++++++++++++
>>   drivers/adc/Kconfig                     |   9 +++
>>   drivers/adc/Makefile                    |   1 +
>>   drivers/adc/exynos-adc.c                | 102 ++++++++++++++++++++++++++++++++
>>   4 files changed, 157 insertions(+)
>>   create mode 100644 drivers/adc/exynos-adc.c
>>
>> diff --git a/arch/arm/mach-exynos/include/mach/adc.h b/arch/arm/mach-exynos/include/mach/adc.h
>> index a0e26d7..228acf4 100644
>> --- a/arch/arm/mach-exynos/include/mach/adc.h
>> +++ b/arch/arm/mach-exynos/include/mach/adc.h
>> @@ -9,6 +9,38 @@
>>   #ifndef __ASM_ARM_ARCH_ADC_H_
>>   #define __ASM_ARM_ARCH_ADC_H_
>>
>> +#define ADC_V2_CON1_SOFT_RESET         (0x2 << 1)
>> +#define ADC_V2_CON1_STC_EN             (0x1)
>
> No need for brackets on these simple ones
>

Okay, I will remove them.

>> +
>> +#define ADC_V2_CON2_OSEL(x)            (((x) & 0x1) << 10)
>> +#define OSEL_2S                                (0x0)
>> +#define OSEL_BINARY                    (0x1)
>> +#define ADC_V2_CON2_ESEL(x)            (((x) & 0x1) << 9)
>> +#define ESEL_ADC_EVAL_TIME_40CLK       (0x0)
>> +#define ESEL_ADC_EVAL_TIME_20CLK       (0x1)
>> +#define ADC_V2_CON2_HIGHF(x)           (((x) & 0x1) << 8)
>> +#define HIGHF_CONV_RATE_30KSPS         (0x0)
>> +#define HIGHF_CONV_RATE_600KSPS                (0x1)
>> +#define ADC_V2_CON2_C_TIME(x)          (((x) & 0x7) << 4)
>> +#define ADC_V2_CON2_CHAN_SEL(x)                ((x) & 0xf)
>> +
>> +#define ADC_V2_GET_STATUS_FLAG(x)      (((x) >> 2) & 0x1)
>> +#define FLAG_CONV_END                  (0x1)
>> +
>> +#define ADC_V2_INT_DISABLE             (0x0)
>> +#define ADC_V2_INT_ENABLE              (0x1)
>> +#define INT_NOT_GENERATED              (0x0)
>> +#define INT_GENERATED                  (0x1)
>> +
>> +#define ADC_V2_VERSION                 (0x80000008)
>> +
>> +#define ADC_V2_MAX_CHANNEL             (9)
>> +
>> +/* For default 8 time convertion with sample rate 600 kSPS - 15us timeout */
>> +#define ADC_V2_CONV_TIMEOUT_US         (15)
>> +
>> +#define ADC_V2_DAT_MASK                        (0xfff)
>> +
>>   #ifndef __ASSEMBLY__
>>   struct s5p_adc {
>>          unsigned int adccon;
>> @@ -21,6 +53,19 @@ struct s5p_adc {
>>          unsigned int adcmux;
>>          unsigned int adcclrintpndnup;
>>   };
>> +
>> +struct exynos_adc_v2 {
>> +       unsigned int con1;
>> +       unsigned int con2;
>> +       unsigned int status;
>> +       unsigned int dat;
>> +       unsigned int int_en;
>> +       unsigned int int_status;
>> +       unsigned int reserved[2];
>> +       unsigned int version;
>> +};
>> +
>> +int exynos_adc_read_channel(int channel);
>>   #endif
>>
>>   #endif /* __ASM_ARM_ARCH_ADC_H_ */
>> diff --git a/drivers/adc/Kconfig b/drivers/adc/Kconfig
>> index 1cb1a8d..8ee6531 100644
>> --- a/drivers/adc/Kconfig
>> +++ b/drivers/adc/Kconfig
>> @@ -6,3 +6,12 @@ config ADC
>>            - device enable
>>            - conversion init
>>            - conversion start and return data with data mask
>> +
>> +config ADC_EXYNOS
>> +       bool "Enable Exynos 54xx ADC driver"
>> +       help
>> +         This enables basic driver for Exynos ADC compatible with Exynos54xx.
>> +         It provides:
>> +         - 10 analog input channels
>> +         - 12-bit resolution
>> +         - 600 KSPS of sample rate
>
> Great help!
>

Thanks:)

>> diff --git a/drivers/adc/Makefile b/drivers/adc/Makefile
>> index c4d9618..eb85b8b 100644
>> --- a/drivers/adc/Makefile
>> +++ b/drivers/adc/Makefile
>> @@ -6,3 +6,4 @@
>>   #
>>
>>   obj-$(CONFIG_ADC) += adc-uclass.o
>> +obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
>> diff --git a/drivers/adc/exynos-adc.c b/drivers/adc/exynos-adc.c
>> new file mode 100644
>> index 0000000..fdffea0
>> --- /dev/null
>> +++ b/drivers/adc/exynos-adc.c
>> @@ -0,0 +1,102 @@
>> +/*
>> + * Copyright (C) 2015 Samsung Electronics
>> + * Przemyslaw Marczak <p.marczak@samsung.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +#include <common.h>
>> +#include <errno.h>
>> +#include <dm.h>
>> +#include <adc.h>
>> +#include <asm/arch/adc.h>
>> +
>> +struct exynos_adc_priv {
>> +       struct exynos_adc_v2 *regs;
>> +};
>> +
>> +extern void sdelay(unsigned long loops);
>
> Can you put this include system.h for exynos, or similar? Also, I
> think the problem is that timer_init() is called after initf_dm().
> There is a patch to add timer support to driver model so perhaps that
> will help?
>

Ok, will move this. And yes, the problem is with too late timer init.
I saw the work for timer uclass, however I would prefer just use this 
function. It can be moved in the future.

I'm trying add simple functionality, move everything to driver model is 
not related to this patch set.

We can add the timer driver later, and then fix each timer call.

>> +
>> +int exynos_adc_data(struct udevice *dev, unsigned int *data)
>> +{
>> +       struct exynos_adc_priv *priv = dev_get_priv(dev);
>> +       struct exynos_adc_v2 *regs = priv->regs;
>> +       unsigned int cfg, timeout_us = ADC_V2_CONV_TIMEOUT_US;
>> +
>> +       /* Start conversion */
>> +       cfg = readl(&regs->con1);
>> +       writel(cfg | ADC_V2_CON1_STC_EN, &regs->con1);
>> +
>> +       while (ADC_V2_GET_STATUS_FLAG(readl(&regs->status)) != FLAG_CONV_END) {
>> +               sdelay(4);
>> +               if (!timeout_us--) {
>> +                       error("ADC conversion timeout!");
>> +                       return -ETIME;
>> +               }
>> +       }
>
> Hmm, we don't want to put delays in drivers. I though that the init()
> method was used to start the conversion, but now I see that it is not.
> I think the uclass is going to have to know how long to wait for the
> conversion to be ready.

Good point, I will move the delay to uclass driver.

>
> How about this for an interface:
>
> adc_start(dev, channel)
> adc_read(dev, channel)
>
> which waits until the conversion is ready on that channel. The driver
> can set up the time that the conversion will be ready (and store it in
> the uclass) when the conversion starts.

Ok, that sounds good.

>
> Can we support conversions on several channels at once?
>

Some hardware can do this, but the Exynos internal ADC is simple and 
allows only for a single channel conversion at a time.

I can add an uclass operation function call, e.g. adc_channels_data(), 
and if it's not implemented by the device driver, then it can get the 
data for each channel in a loop.

Is that good to you?

>> +
>> +       *data = readl(&regs->dat) & ADC_V2_DAT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +int exynos_adc_init(struct udevice *dev, int channel)
>> +{
>> +       struct exynos_adc_priv *priv = dev_get_priv(dev);
>> +       struct exynos_adc_v2 *regs = priv->regs;
>> +       unsigned int cfg;
>> +
>> +       /* Check HW version */
>> +       if (readl(&regs->version) != ADC_V2_VERSION) {
>> +               error("This driver supports only ADC v2!");
>> +               return -ENXIO;
>> +       }
>> +
>> +       /* ADC Reset */
>> +       writel(ADC_V2_CON1_SOFT_RESET, &regs->con1);
>> +
>> +       /* Disable INT - will read status only */
>> +       writel(0x0, &regs->int_en);
>> +
>> +       /* CON2 - set conversion parameters */
>> +       cfg = ADC_V2_CON2_C_TIME(3); /* Conversion times: (1 << 3) = 8 */
>> +       cfg |= ADC_V2_CON2_OSEL(OSEL_BINARY);
>> +       cfg |= ADC_V2_CON2_CHAN_SEL(channel);
>> +       cfg |= ADC_V2_CON2_ESEL(ESEL_ADC_EVAL_TIME_20CLK);
>> +       cfg |= ADC_V2_CON2_HIGHF(HIGHF_CONV_RATE_600KSPS);
>> +       writel(cfg, &regs->con2);
>
> Can this function go in probe() instead? The only thing that can't is
> 'channel'. Is that setting which channel does the conversion? If so,
> perhaps that particular setting could move to the start function?
>

Yes, those settings should be done before each conversion.

>> +
>> +       return 0;
>> +}
>> +
>> +int exynos_adc_ofdata_to_platdata(struct udevice *dev)
>> +{
>> +       struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
>> +       struct exynos_adc_priv *priv = dev_get_priv(dev);
>> +
>> +       priv->regs = (struct exynos_adc_v2 *)dev_get_addr(dev);
>> +
>> +       uc_pdata->data_mask = ADC_V2_DAT_MASK;
>> +       /* Channel count starts from 0 */
>> +       uc_pdata->channels_num = ADC_V2_MAX_CHANNEL + 1;
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct adc_ops exynos_adc_ops = {
>> +       .adc_init = exynos_adc_init,
>> +       .adc_data = exynos_adc_data,
>> +};
>> +
>> +static const struct udevice_id exynos_adc_ids[] = {
>> +       { .compatible = "samsung,exynos-adc-v2" },
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(exynos_adc) = {
>> +       .name           = "exynos-adc",
>> +       .id             = UCLASS_ADC,
>> +       .of_match       = exynos_adc_ids,
>> +       .ops            = &exynos_adc_ops,
>> +       .ofdata_to_platdata = exynos_adc_ofdata_to_platdata,
>> +       .priv_auto_alloc_size = sizeof(struct exynos_adc_priv),
>> +};
>> --
>> 1.9.1
>>
>
> Regards,
> Simon
>

Best regards
-- 
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marczak at samsung.com

  reply	other threads:[~2015-10-13 11:58 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-28 13:59 [U-Boot] [PATCH 0/7] Add board detection for Odroid XU3 / XU3Lite / XU4 Przemyslaw Marczak
2015-08-28 13:59 ` [U-Boot] [PATCH 1/7] s5p: cpu_info: use defined CPU name if available Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-09-04 15:04     ` Przemyslaw Marczak
2015-08-28 13:59 ` [U-Boot] [PATCH 2/7] peach-pi: define CPU name for SoC Exynos5800 Przemyslaw Marczak
2015-08-28 13:59 ` [U-Boot] [PATCH 3/7] Exynos5422/5800: set cpu id to 0x5422 Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-08-28 13:59 ` [U-Boot] [PATCH 4/7] dm: pmic: add s2mps11 PMIC I/O driver Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-09-04 15:04     ` Przemyslaw Marczak
2015-09-07  0:11   ` Minkyu Kang
2015-09-09 10:31     ` Przemyslaw Marczak
2015-08-28 13:59 ` [U-Boot] [PATCH 5/7] odroid-xu3: enable s2mps11 PMIC support Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-08-28 13:59 ` [U-Boot] [PATCH 6/7] Exynos: add internal ADC driver Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-09-04 15:04     ` Przemyslaw Marczak
2015-08-28 13:59 ` [U-Boot] [PATCH 7/7] exynos5-dt: add board detection for Odroid XU3/XU3L/XU4 Przemyslaw Marczak
2015-09-01  0:33   ` Simon Glass
2015-09-04 15:04     ` Przemyslaw Marczak
2015-08-30 19:03 ` [U-Boot] [PATCH 0/7] Add board detection for Odroid XU3 / XU3Lite / XU4 Anand Moon
2015-08-31 12:17   ` Przemyslaw Marczak
2015-10-21  1:58   ` Siarhei Siamashka
2015-10-21  9:47     ` Anand Moon
2015-10-21  9:57     ` Anand Moon
2015-10-21 10:13       ` Przemyslaw Marczak
2015-08-31 13:22 ` Simon Glass
2015-08-31 18:29   ` Przemyslaw Marczak
2015-08-31 23:13     ` Simon Glass
2015-09-04 15:04       ` Przemyslaw Marczak
2015-09-21 12:26 ` [U-Boot] [PATCH V2 00/11] " Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 01/11] samsung: board/misc: check returned pointer for get_board_type() calls Przemyslaw Marczak
2015-10-03 14:27     ` Simon Glass
2015-09-21 12:26   ` [U-Boot] [PATCH V2 02/11] s5p: cpu_info: print "cpu-model" if exists in dts Przemyslaw Marczak
2015-10-03 14:27     ` Simon Glass
2015-10-13 11:57       ` Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 03/11] Peach-Pi: dts: add cpu-model string Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-10-13 11:57       ` Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 04/11] Exynos5422/5800: set cpu id to 0x5422 Przemyslaw Marczak
2015-09-21 12:47     ` Jaehoon Chung
2015-09-21 13:01       ` Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 05/11] dm: pmic: add s2mps11 PMIC I/O driver Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-10-13 11:57       ` Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 06/11] dm: adc: add simple ADC uclass implementation Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-10-13 11:57       ` Przemyslaw Marczak
2015-09-21 12:26   ` [U-Boot] [PATCH V2 07/11] dm: adc: add Exynos54xx compatible ADC driver Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-10-13 11:58       ` Przemyslaw Marczak [this message]
2015-10-19  2:20         ` Simon Glass
2015-09-21 12:26   ` [U-Boot] [PATCH V2 08/11] Odroid-XU3: enable s2mps11 PMIC support Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-09-21 12:26   ` [U-Boot] [PATCH V2 09/11] Exynos54xx: dts: add ADC node Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-09-21 12:26   ` [U-Boot] [PATCH V2 10/11] Odroid-XU3: dts: enable ADC, with request for pre-reloc bind Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-09-21 12:26   ` [U-Boot] [PATCH V2 11/11] exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4 Przemyslaw Marczak
2015-10-03 14:28     ` Simon Glass
2015-10-13 11:59       ` Przemyslaw Marczak
2015-10-19  2:21         ` Simon Glass
2015-09-27 12:20   ` [U-Boot] [PATCH V2 00/11] Add board detection for Odroid XU3 / XU3Lite / XU4 Anand Moon
2015-09-28 10:19     ` Przemyslaw Marczak
2015-10-01 11:07   ` Przemyslaw Marczak
2015-10-03 14:30     ` Simon Glass
2015-10-13 11:59       ` Przemyslaw Marczak
2015-10-27 12:07   ` [U-Boot] [PATCH V3 00/14] " Przemyslaw Marczak
2015-10-27 12:07     ` [U-Boot] [PATCH V3 01/14] samsung: board/misc: check returned pointer for get_board_type() calls Przemyslaw Marczak
2015-10-28 18:50       ` Simon Glass
2015-10-30  3:00         ` Anand Moon
2015-10-27 12:07     ` [U-Boot] [PATCH V3 02/14] s5p: cpu_info: print "cpu-model" if exists in dts Przemyslaw Marczak
2015-10-28 18:50       ` Simon Glass
2015-10-30  3:01       ` Anand Moon
2015-10-27 12:07     ` [U-Boot] [PATCH V3 03/14] Peach-Pi: dts: add cpu-model string Przemyslaw Marczak
2015-10-28 18:50       ` Simon Glass
2015-10-30  3:02       ` Anand Moon
2015-10-27 12:07     ` [U-Boot] [PATCH V3 04/14] Exynos5422/5800: set cpu id to 0x5422 Przemyslaw Marczak
2015-10-30  3:03       ` Anand Moon
2015-10-27 12:07     ` [U-Boot] [PATCH V3 05/14] dm: pmic: add s2mps11 PMIC I/O driver Przemyslaw Marczak
2015-10-28 18:50       ` Simon Glass
2015-10-30  3:04       ` Anand Moon
2015-10-27 12:07     ` [U-Boot] [PATCH V3 06/14] dm: regulator: add function device_get_supply_regulator() Przemyslaw Marczak
2015-11-05 18:25       ` Simon Glass
2015-10-27 12:08     ` [U-Boot] [PATCH V3 07/14] dm: adc: add simple ADC uclass implementation Przemyslaw Marczak
2015-10-27 13:53       ` Przemyslaw Marczak
2015-11-05 18:25       ` Simon Glass
2015-10-27 12:08     ` [U-Boot] [PATCH V3 08/14] dm: adc: add Exynos54xx compatible ADC driver Przemyslaw Marczak
2015-11-06  0:15       ` Simon Glass
2015-10-27 12:08     ` [U-Boot] [PATCH V3 09/14] Odroid-XU3: enable s2mps11 PMIC support Przemyslaw Marczak
2015-10-30  3:09       ` Anand Moon
2015-10-27 12:08     ` [U-Boot] [PATCH V3 10/14] Exynos54xx: dts: add ADC node Przemyslaw Marczak
2015-10-28 18:50       ` Simon Glass
2015-10-29 13:58         ` Przemyslaw Marczak
2015-11-06  3:15           ` Simon Glass
2015-11-06  8:48             ` Przemyslaw Marczak
2015-10-27 12:08     ` [U-Boot] [PATCH V3 11/14] Odroid-XU3: dts: enable ADC, with request for pre-reloc bind Przemyslaw Marczak
2015-10-27 12:08     ` [U-Boot] [PATCH V3 12/14] exynos5-dt-types: add board detection for Odroid XU3/XU3L/XU4 Przemyslaw Marczak
2015-10-30  3:06       ` Anand Moon
2015-10-27 12:08     ` [U-Boot] [PATCH V3 13/14] sandbox: add ADC driver Przemyslaw Marczak
2015-11-04  9:52       ` [U-Boot] [PATCH] Add missing file: include/sandbox-adc.h Przemyslaw Marczak
2015-11-06 12:07         ` Simon Glass
2015-11-06  0:15       ` [U-Boot] [PATCH V3 13/14] sandbox: add ADC driver Simon Glass
2015-10-27 12:08     ` [U-Boot] [PATCH V3 14/14] sandbox: add ADC unit tests Przemyslaw Marczak
2015-11-06  0:15       ` Simon Glass
2015-11-02  5:37     ` [U-Boot] [PATCH V3 00/14] Add board detection for Odroid XU3 / XU3Lite / XU4 Minkyu Kang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=561CF1F1.4010801@samsung.com \
    --to=p.marczak@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox