[PATCHv6 1/4] iio: adc: exynos_adc: Add exynos_adc_data structure to improve readability

2014-07-18 Thread Chanwoo Choi
This patchset add 'exynos_adc_data' structure which includes some functions
to control ADC operation and specific data according to ADC version (v1 or v2).

Signed-off-by: Chanwoo Choi cw00.c...@samsung.com
Acked-by: Kyungmin Park kyungmin.p...@samsung.com
Reviewed-by: Naveen Krishna Chatradhi ch.nav...@samsung.com
Reviewed-by: Tomasz Figa t.f...@samsung.com
---
 drivers/iio/adc/exynos_adc.c | 226 ---
 1 file changed, 147 insertions(+), 79 deletions(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 010578f..00d67fd 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -39,11 +39,6 @@
 #include linux/iio/machine.h
 #include linux/iio/driver.h
 
-enum adc_version {
-   ADC_V1,
-   ADC_V2
-};
-
 /* EXYNOS4412/5250 ADC_V1 registers definitions */
 #define ADC_V1_CON(x)  ((x) + 0x00)
 #define ADC_V1_DLY(x)  ((x) + 0x08)
@@ -85,6 +80,7 @@ enum adc_version {
 #define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100))
 
 struct exynos_adc {
+   struct exynos_adc_data  *data;
void __iomem*regs;
void __iomem*enable_reg;
struct clk  *clk;
@@ -97,43 +93,139 @@ struct exynos_adc {
unsigned intversion;
 };
 
-static const struct of_device_id exynos_adc_match[] = {
-   { .compatible = samsung,exynos-adc-v1, .data = (void *)ADC_V1 },
-   { .compatible = samsung,exynos-adc-v2, .data = (void *)ADC_V2 },
-   {},
+struct exynos_adc_data {
+   int num_channels;
+
+   void (*init_hw)(struct exynos_adc *info);
+   void (*exit_hw)(struct exynos_adc *info);
+   void (*clear_irq)(struct exynos_adc *info);
+   void (*start_conv)(struct exynos_adc *info, unsigned long addr);
 };
-MODULE_DEVICE_TABLE(of, exynos_adc_match);
 
-static inline unsigned int exynos_adc_get_version(struct platform_device *pdev)
+static void exynos_adc_v1_init_hw(struct exynos_adc *info)
 {
-   const struct of_device_id *match;
+   u32 con1;
 
-   match = of_match_node(exynos_adc_match, pdev-dev.of_node);
-   return (unsigned int)match-data;
+   writel(1, info-enable_reg);
+
+   /* set default prescaler values and Enable prescaler */
+   con1 =  ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+
+   /* Enable 12-bit ADC resolution */
+   con1 |= ADC_V1_CON_RES;
+   writel(con1, ADC_V1_CON(info-regs));
+}
+
+static void exynos_adc_v1_exit_hw(struct exynos_adc *info)
+{
+   u32 con;
+
+   writel(0, info-enable_reg);
+
+   con = readl(ADC_V1_CON(info-regs));
+   con |= ADC_V1_CON_STANDBY;
+   writel(con, ADC_V1_CON(info-regs));
+}
+
+static void exynos_adc_v1_clear_irq(struct exynos_adc *info)
+{
+   writel(1, ADC_V1_INTCLR(info-regs));
 }
 
-static void exynos_adc_hw_init(struct exynos_adc *info)
+static void exynos_adc_v1_start_conv(struct exynos_adc *info,
+unsigned long addr)
+{
+   u32 con1;
+
+   writel(addr, ADC_V1_MUX(info-regs));
+
+   con1 = readl(ADC_V1_CON(info-regs));
+   writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info-regs));
+}
+
+static struct exynos_adc_data const exynos_adc_v1_data = {
+   .num_channels   = MAX_ADC_V1_CHANNELS,
+
+   .init_hw= exynos_adc_v1_init_hw,
+   .exit_hw= exynos_adc_v1_exit_hw,
+   .clear_irq  = exynos_adc_v1_clear_irq,
+   .start_conv = exynos_adc_v1_start_conv,
+};
+
+static void exynos_adc_v2_init_hw(struct exynos_adc *info)
 {
u32 con1, con2;
 
-   if (info-version == ADC_V2) {
-   con1 = ADC_V2_CON1_SOFT_RESET;
-   writel(con1, ADC_V2_CON1(info-regs));
+   writel(1, info-enable_reg);
 
-   con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
-   ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
-   writel(con2, ADC_V2_CON2(info-regs));
+   con1 = ADC_V2_CON1_SOFT_RESET;
+   writel(con1, ADC_V2_CON1(info-regs));
 
-   /* Enable interrupts */
-   writel(1, ADC_V2_INT_EN(info-regs));
-   } else {
-   /* set default prescaler values and Enable prescaler */
-   con1 =  ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN;
+   con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |
+   ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);
+   writel(con2, ADC_V2_CON2(info-regs));
 
-   /* Enable 12-bit ADC resolution */
-   con1 |= ADC_V1_CON_RES;
-   writel(con1, ADC_V1_CON(info-regs));
-   }
+   /* Enable interrupts */
+   writel(1, ADC_V2_INT_EN(info-regs));
+}
+
+static void exynos_adc_v2_exit_hw(struct exynos_adc *info)
+{
+   u32 con;
+
+   writel(0, info-enable_reg);
+
+   con = readl(ADC_V2_CON1(info-regs));
+   con = ~ADC_CON_EN_START;
+   writel(con, ADC_V2_CON1(info-regs));
+}
+
+static void exynos_adc_v2_clear_irq(struct exynos_adc *info)
+{
+

Re: [PATCHv6 1/4] iio: adc: exynos_adc: Add exynos_adc_data structure to improve readability

2014-07-18 Thread Arnd Bergmann
On Friday 18 July 2014 14:59:43 Chanwoo Choi wrote:
 This patchset add 'exynos_adc_data' structure which includes some functions
 to control ADC operation and specific data according to ADC version (v1 or 
 v2).
 

This new structure makes a lot of sense for covering the exynos specific
versions, but it will likely give a little more complexity for the
older models. We'll have to deal with that later then, no need to
hold up your patch. Interestingly, the version numbers seem weird. The
old driver uses

{
.name   = s3c24xx-adc,
.driver_data= TYPE_ADCV1,
}, {
.name   = s3c2443-adc,
.driver_data= TYPE_ADCV11,
}, {
.name   = s3c2416-adc,
.driver_data= TYPE_ADCV12,
}, {
.name   = s3c64xx-adc,
.driver_data= TYPE_ADCV2,
}, {
.name   = samsung-adc-v3,
.driver_data= TYPE_ADCV3,
}

Where TYPE_ADCV3 seems to be the same as the new ADC_V1 used in this
driver. Do you have an explanation for that?

Arnd
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv6 1/4] iio: adc: exynos_adc: Add exynos_adc_data structure to improve readability

2014-07-18 Thread Naveen Krishna Ch
Hello Arnd,

On 18 July 2014 15:12, Arnd Bergmann a...@arndb.de wrote:
 On Friday 18 July 2014 14:59:43 Chanwoo Choi wrote:
 This patchset add 'exynos_adc_data' structure which includes some functions
 to control ADC operation and specific data according to ADC version (v1 or 
 v2).


 This new structure makes a lot of sense for covering the exynos specific
 versions, but it will likely give a little more complexity for the
 older models. We'll have to deal with that later then, no need to
 hold up your patch. Interestingly, the version numbers seem weird. The
 old driver uses

 {
 .name   = s3c24xx-adc,
 .driver_data= TYPE_ADCV1,
 }, {
 .name   = s3c2443-adc,
 .driver_data= TYPE_ADCV11,
 }, {
 .name   = s3c2416-adc,
 .driver_data= TYPE_ADCV12,
 }, {
 .name   = s3c64xx-adc,
 .driver_data= TYPE_ADCV2,
 }, {
 .name   = samsung-adc-v3,
 .driver_data= TYPE_ADCV3,
 }

 Where TYPE_ADCV3 seems to be the same as the new ADC_V1 used in this
 driver. Do you have an explanation for that?

As per suggestion from Doug Anderson,
I've implemented IIO based ADC driver to work with Exynos5250.
keeping the plat-samsung/adc.c unchanged.

Assuming Exynos5250 is the one using the driver for the first time.
i've named it v1 and so on.

Now, This seems to cause a lot of confusion.


 Arnd
 --
 To unsubscribe from this list: send the line unsubscribe linux-iio in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Shine bright,
(: Nav :)
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv6 1/4] iio: adc: exynos_adc: Add exynos_adc_data structure to improve readability

2014-07-18 Thread Arnd Bergmann
On Friday 18 July 2014 15:41:27 Naveen Krishna Ch wrote:
 
  {
  .name   = s3c24xx-adc,
  .driver_data= TYPE_ADCV1,
  }, {
  .name   = s3c2443-adc,
  .driver_data= TYPE_ADCV11,
  }, {
  .name   = s3c2416-adc,
  .driver_data= TYPE_ADCV12,
  }, {
  .name   = s3c64xx-adc,
  .driver_data= TYPE_ADCV2,
  }, {
  .name   = samsung-adc-v3,
  .driver_data= TYPE_ADCV3,
  }
 
  Where TYPE_ADCV3 seems to be the same as the new ADC_V1 used in this
  driver. Do you have an explanation for that?
 
 As per suggestion from Doug Anderson,
 I've implemented IIO based ADC driver to work with Exynos5250.
 keeping the plat-samsung/adc.c unchanged.
 
 Assuming Exynos5250 is the one using the driver for the first time.
 i've named it v1 and so on.
 
 Now, This seems to cause a lot of confusion.

Ah, so the version numbers don't come from Samsung hardware
documents but are just counting the versions we have drivers
for?

In this case, I guess using the first SoC that had a particular
version would have been better, and we should probably do that
when we add support for the older hardware in this driver.

Arnd
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html