ARM: SAMSUNG: Add support for 12bit ADC
authorMaurus Cuelenaere <mcuelenaere@gmail.com>
Sat, 30 Jan 2010 17:01:48 +0000 (18:01 +0100)
committerBen Dooks <ben-linux@fluff.org>
Wed, 3 Feb 2010 01:55:04 +0000 (01:55 +0000)
The S3C64XX SoC series support 12bit ADC data, enable this and
mask the data accordingly.

Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com>
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
arch/arm/plat-samsung/adc.c
arch/arm/plat-samsung/include/plat/regs-adc.h

index c7659b7..81caf21 100644 (file)
@@ -262,6 +262,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
 {
        struct adc_device *adc = pw;
        struct s3c_adc_client *client = adc->cur;
+       enum s3c_cpu_type cpu = platform_get_device_id(adc->pdev)->driver_data;
        unsigned long flags;
        unsigned data0, data1;
 
@@ -276,9 +277,17 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
 
        client->nr_samples--;
 
+       if (cpu == TYPE_S3C64XX) {
+               /* S3C64XX ADC resolution is 12-bit */
+               data0 &= 0xfff;
+               data1 &= 0xfff;
+       } else {
+               data0 &= 0x3ff;
+               data1 &= 0x3ff;
+       }
+
        if (client->convert_cb)
-               (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
-                                    &client->nr_samples);
+               (client->convert_cb)(client, data0, data1, &client->nr_samples);
 
        if (client->nr_samples > 0) {
                /* fire another conversion for this */
@@ -295,7 +304,7 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
        }
 
 exit:
-       if (platform_get_device_id(adc->pdev)->driver_data == TYPE_S3C64XX) {
+       if (cpu == TYPE_S3C64XX) {
                /* Clear ADC interrupt */
                writel(0, adc->regs + S3C64XX_ADCCLRINT);
        }
@@ -308,6 +317,7 @@ static int s3c_adc_probe(struct platform_device *pdev)
        struct adc_device *adc;
        struct resource *regs;
        int ret;
+       unsigned tmp;
 
        adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
        if (adc == NULL) {
@@ -354,8 +364,12 @@ static int s3c_adc_probe(struct platform_device *pdev)
 
        clk_enable(adc->clk);
 
-       writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
-              adc->regs + S3C2410_ADCCON);
+       tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+       if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
+               /* Enable 12-bit ADC resolution */
+               tmp |= S3C64XX_ADCCON_RESSEL;
+       }
+       writel(tmp, adc->regs + S3C2410_ADCCON);
 
        dev_info(dev, "attached adc driver\n");
 
index f43c8da..7554c4f 100644 (file)
@@ -25,6 +25,7 @@
 
 
 /* ADCCON Register Bits */
+#define S3C64XX_ADCCON_RESSEL          (1<<16)
 #define S3C2410_ADCCON_ECFLG           (1<<15)
 #define S3C2410_ADCCON_PRSCEN          (1<<14)
 #define S3C2410_ADCCON_PRSCVL(x)       (((x)&0xFF)<<6)