The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/freescale/vybrid/vf_adc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 /*
   28  * Vybrid Family 12-bit Analog to Digital Converter (ADC)
   29  * Chapter 37, Vybrid Reference Manual, Rev. 5, 07/2013
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/bus.h>
   38 #include <sys/kernel.h>
   39 #include <sys/module.h>
   40 #include <sys/malloc.h>
   41 #include <sys/rman.h>
   42 #include <sys/timeet.h>
   43 #include <sys/timetc.h>
   44 
   45 #include <dev/ofw/openfirm.h>
   46 #include <dev/ofw/ofw_bus.h>
   47 #include <dev/ofw/ofw_bus_subr.h>
   48 
   49 #include <machine/bus.h>
   50 #include <machine/cpu.h>
   51 #include <machine/intr.h>
   52 
   53 #include <arm/freescale/vybrid/vf_common.h>
   54 #include <arm/freescale/vybrid/vf_adc.h>
   55 
   56 #define ADC_HC0         0x00            /* Ctrl reg for hardware triggers */
   57 #define ADC_HC1         0x04            /* Ctrl reg for hardware triggers */
   58 #define  HC_AIEN        (1 << 7)        /* Conversion Complete Int Control */
   59 #define  HC_ADCH_M      0x1f            /* Input Channel Select Mask */
   60 #define  HC_ADCH_S      0               /* Input Channel Select Shift */
   61 #define ADC_HS          0x08            /* Status register for HW triggers */
   62 #define  HS_COCO0       (1 << 0)        /* Conversion Complete Flag */
   63 #define  HS_COCO1       (1 << 1)        /* Conversion Complete Flag */
   64 #define ADC_R0          0x0C            /* Data result reg for HW triggers */
   65 #define ADC_R1          0x10            /* Data result reg for HW triggers */
   66 #define ADC_CFG         0x14            /* Configuration register */
   67 #define  CFG_OVWREN     (1 << 16)       /* Data Overwrite Enable */
   68 #define  CFG_AVGS_M     0x3             /* Hardware Average select Mask */
   69 #define  CFG_AVGS_S     14              /* Hardware Average select Shift */
   70 #define  CFG_ADTRG      (1 << 13)       /* Conversion Trigger Select */
   71 #define  CFG_REFSEL_M   0x3             /* Voltage Reference Select Mask */
   72 #define  CFG_REFSEL_S   11              /* Voltage Reference Select Shift */
   73 #define  CFG_ADHSC      (1 << 10)       /* High Speed Configuration */
   74 #define  CFG_ADSTS_M    0x3             /* Defines the sample time duration */
   75 #define  CFG_ADSTS_S    8               /* Defines the sample time duration */
   76 #define  CFG_ADLPC      (1 << 7)        /* Low-Power Configuration */
   77 #define  CFG_ADIV_M     0x3             /* Clock Divide Select */
   78 #define  CFG_ADIV_S     5               /* Clock Divide Select */
   79 #define  CFG_ADLSMP     (1 << 4)        /* Long Sample Time Configuration */
   80 #define  CFG_MODE_M     0x3             /* Conversion Mode Selection Mask */
   81 #define  CFG_MODE_S     2               /* Conversion Mode Selection Shift */
   82 #define  CFG_MODE_12    0x2             /* 12-bit mode */
   83 #define  CFG_ADICLK_M   0x3             /* Input Clock Select Mask */
   84 #define  CFG_ADICLK_S   0               /* Input Clock Select Shift */
   85 #define ADC_GC          0x18            /* General control register */
   86 #define  GC_CAL         (1 << 7)        /* Calibration */
   87 #define  GC_ADCO        (1 << 6)        /* Continuous Conversion Enable */
   88 #define  GC_AVGE        (1 << 5)        /* Hardware average enable */
   89 #define  GC_ACFE        (1 << 4)        /* Compare Function Enable */
   90 #define  GC_ACFGT       (1 << 3)        /* Compare Function Greater Than En */
   91 #define  GC_ACREN       (1 << 2)        /* Compare Function Range En */
   92 #define  GC_DMAEN       (1 << 1)        /* DMA Enable */
   93 #define  GC_ADACKEN     (1 << 0)        /* Asynchronous clock output enable */
   94 #define ADC_GS          0x1C            /* General status register */
   95 #define  GS_AWKST       (1 << 2)        /* Asynchronous wakeup int status */
   96 #define  GS_CALF        (1 << 1)        /* Calibration Failed Flag */
   97 #define  GS_ADACT       (1 << 0)        /* Conversion Active */
   98 #define ADC_CV          0x20            /* Compare value register */
   99 #define  CV_CV2_M       0xfff           /* Compare Value 2 Mask */
  100 #define  CV_CV2_S       16              /* Compare Value 2 Shift */
  101 #define  CV_CV1_M       0xfff           /* Compare Value 1 Mask */
  102 #define  CV_CV1_S       0               /* Compare Value 1 Shift */
  103 #define ADC_OFS         0x24            /* Offset correction value register */
  104 #define  OFS_SIGN       12              /* Sign bit */
  105 #define  OFS_M          0xfff           /* Offset value Mask */
  106 #define  OFS_S          0               /* Offset value Shift */
  107 #define ADC_CAL         0x28            /* Calibration value register */
  108 #define  CAL_CODE_M     0xf             /* Calibration Result Value Mask */
  109 #define  CAL_CODE_S     0               /* Calibration Result Value Shift */
  110 #define ADC_PCTL        0x30            /* Pin control register */
  111 
  112 struct adc_softc {
  113         struct resource         *res[2];
  114         bus_space_tag_t         bst;
  115         bus_space_handle_t      bsh;
  116         void                    *ih;
  117 };
  118 
  119 struct adc_softc *adc_sc;
  120 
  121 static struct resource_spec adc_spec[] = {
  122         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  123         { SYS_RES_IRQ,          0,      RF_ACTIVE },
  124         { -1, 0 }
  125 };
  126 
  127 static int
  128 adc_probe(device_t dev)
  129 {
  130 
  131         if (!ofw_bus_status_okay(dev))
  132                 return (ENXIO);
  133 
  134         if (!ofw_bus_is_compatible(dev, "fsl,mvf600-adc"))
  135                 return (ENXIO);
  136 
  137         device_set_desc(dev, "Vybrid Family "
  138             "12-bit Analog to Digital Converter");
  139         return (BUS_PROBE_DEFAULT);
  140 }
  141 
  142 static void
  143 adc_intr(void *arg)
  144 {
  145         struct adc_softc *sc;
  146 
  147         sc = arg;
  148 
  149         /* Conversation complete */
  150 }
  151 
  152 uint32_t
  153 adc_read(void)
  154 {
  155         struct adc_softc *sc;
  156 
  157         sc = adc_sc;
  158         if (sc == NULL)
  159                 return (0);
  160 
  161         return (READ4(sc, ADC_R0));
  162 }
  163 
  164 uint32_t
  165 adc_enable(int channel)
  166 {
  167         struct adc_softc *sc;
  168         int reg;
  169 
  170         sc = adc_sc;
  171         if (sc == NULL)
  172                 return (1);
  173 
  174         reg = READ4(sc, ADC_HC0);
  175         reg &= ~(HC_ADCH_M << HC_ADCH_S);
  176         reg |= (channel << HC_ADCH_S);
  177         WRITE4(sc, ADC_HC0, reg);
  178 
  179         return (0);
  180 }
  181 
  182 static int
  183 adc_attach(device_t dev)
  184 {
  185         struct adc_softc *sc;
  186         int err;
  187         int reg;
  188 
  189         sc = device_get_softc(dev);
  190 
  191         if (bus_alloc_resources(dev, adc_spec, sc->res)) {
  192                 device_printf(dev, "could not allocate resources\n");
  193                 return (ENXIO);
  194         }
  195 
  196         /* Memory interface */
  197         sc->bst = rman_get_bustag(sc->res[0]);
  198         sc->bsh = rman_get_bushandle(sc->res[0]);
  199 
  200         adc_sc = sc;
  201 
  202         /* Setup interrupt handler */
  203         err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE,
  204             NULL, adc_intr, sc, &sc->ih);
  205         if (err) {
  206                 device_printf(dev, "Unable to alloc interrupt resource.\n");
  207                 return (ENXIO);
  208         }
  209 
  210         /* Configure 12-bit mode */
  211         reg = READ4(sc, ADC_CFG);
  212         reg &= ~(CFG_MODE_M << CFG_MODE_S);
  213         reg |= (CFG_MODE_12 << CFG_MODE_S); /* 12bit */
  214         WRITE4(sc, ADC_CFG, reg);
  215 
  216         /* Configure for continuous conversion */
  217         reg = READ4(sc, ADC_GC);
  218         reg |= (GC_ADCO | GC_AVGE);
  219         WRITE4(sc, ADC_GC, reg);
  220 
  221         /* Disable interrupts */
  222         reg = READ4(sc, ADC_HC0);
  223         reg &= HC_AIEN;
  224         WRITE4(sc, ADC_HC0, reg);
  225 
  226         return (0);
  227 }
  228 
  229 static device_method_t adc_methods[] = {
  230         DEVMETHOD(device_probe,         adc_probe),
  231         DEVMETHOD(device_attach,        adc_attach),
  232         { 0, 0 }
  233 };
  234 
  235 static driver_t adc_driver = {
  236         "adc",
  237         adc_methods,
  238         sizeof(struct adc_softc),
  239 };
  240 
  241 static devclass_t adc_devclass;
  242 
  243 DRIVER_MODULE(adc, simplebus, adc_driver, adc_devclass, 0, 0);

Cache object: b5754ec26ce87b371552658f0561f452


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.