iio: at91: ADC start-up time calculation changed since at91sam9x5
authorJosh Wu <josh.wu@atmel.com>
Tue, 8 Oct 2013 03:48:00 +0000 (04:48 +0100)
committerJonathan Cameron <jic23@kernel.org>
Wed, 9 Oct 2013 20:15:32 +0000 (21:15 +0100)
Since in at91sam9x5, sama5d3x chip. the start up time calucation is changed.
This patch can choose different start up time calculation formula for different
chips.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/adc/at91_adc.c

index 8b93295369b0e0efc6e4febab72a05ebfbcb0f81..abce01b9ff91137f96192cbf73f91f5997d73339 100644 (file)
@@ -40,6 +40,9 @@
        (writel_relaxed(val, st->reg_base + reg))
 
 struct at91_adc_caps {
+       /* startup time calculate function */
+       u32 (*calc_startup_ticks)(u8 startup_time, u32 adc_clk_khz);
+
        struct at91_adc_reg_desc registers;
 };
 
@@ -428,6 +431,45 @@ ret:
        return ret;
 }
 
+static u32 calc_startup_ticks_9260(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * Number of ticks needed to cover the startup time of the ADC
+        * as defined in the electrical characteristics of the board,
+        * divided by 8. The formula thus is :
+        *   Startup Time = (ticks + 1) * 8 / ADC Clock
+        */
+       return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8;
+}
+
+static u32 calc_startup_ticks_9x5(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * For sama5d3x and at91sam9x5, the formula changes to:
+        * Startup Time = <lookup_table_value> / ADC Clock
+        */
+       const int startup_lookup[] = {
+               0  , 8  , 16 , 24 ,
+               64 , 80 , 96 , 112,
+               512, 576, 640, 704,
+               768, 832, 896, 960
+               };
+       int i, size = ARRAY_SIZE(startup_lookup);
+       unsigned int ticks;
+
+       ticks = startup_time * adc_clk_khz / 1000;
+       for (i = 0; i < size; i++)
+               if (ticks < startup_lookup[i])
+                       break;
+
+       ticks = i;
+       if (ticks == size)
+               /* Reach the end of lookup table */
+               ticks = size - 1;
+
+       return ticks;
+}
+
 static const struct of_device_id at91_adc_dt_ids[];
 
 static int at91_adc_probe_dt(struct at91_adc_state *st,
@@ -651,14 +693,8 @@ static int at91_adc_probe(struct platform_device *pdev)
                ret = -EINVAL;
                goto error_disable_adc_clk;
        }
+       ticks = (*st->caps->calc_startup_ticks)(st->startup_time, adc_clk_khz);
 
-       /*
-        * Number of ticks needed to cover the startup time of the ADC as
-        * defined in the electrical characteristics of the board, divided by 8.
-        * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock
-        */
-       ticks = round_up((st->startup_time * adc_clk_khz /
-                         1000) - 1, 8) / 8;
        /*
         * a minimal Sample and Hold Time is necessary for the ADC to guarantee
         * the best converted final value between two channels selection
@@ -736,6 +772,7 @@ static int at91_adc_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
 static struct at91_adc_caps at91sam9260_caps = {
+       .calc_startup_ticks = calc_startup_ticks_9260,
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -747,6 +784,7 @@ static struct at91_adc_caps at91sam9260_caps = {
 };
 
 static struct at91_adc_caps at91sam9g45_caps = {
+       .calc_startup_ticks = calc_startup_ticks_9260,  /* same as 9260 */
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -758,6 +796,7 @@ static struct at91_adc_caps at91sam9g45_caps = {
 };
 
 static struct at91_adc_caps at91sam9x5_caps = {
+       .calc_startup_ticks = calc_startup_ticks_9x5,
        .registers = {
                .channel_base = AT91_ADC_CDR0_9X5,
                .drdy_mask = AT91_ADC_SR_DRDY_9X5,