<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://wiki.gumstix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bart</id>
		<title>Gumstix User Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.gumstix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bart"/>
		<link rel="alternate" type="text/html" href="https://wiki.gumstix.com/index.php/Special:Contributions/Bart"/>
		<updated>2026-04-27T08:37:44Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.3</generator>

	<entry>
		<id>https://wiki.gumstix.com/index.php?title=ADC_overo_2.6.38-&amp;diff=5742</id>
		<title>ADC overo 2.6.38-</title>
		<link rel="alternate" type="text/html" href="https://wiki.gumstix.com/index.php?title=ADC_overo_2.6.38-&amp;diff=5742"/>
				<updated>2012-01-10T15:19:18Z</updated>
		
		<summary type="html">&lt;p&gt;Bart: fixed some bugs in the example program&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;For overo's running kernel 2.6.38 and earlier&lt;br /&gt;
&lt;br /&gt;
Use /dev/twl4030 to access the adc's&lt;br /&gt;
&lt;br /&gt;
See Scott Ellis' page&lt;br /&gt;
&lt;br /&gt;
http://www.jumpnowtek.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=79&amp;amp;Itemid=91&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The source code uses the ‘twl4030’ as a name - which is also an older chip from TI. The TPS65950 on the OMAP board is pin-compatible and uses the same/similar ADC module so the older code works nicely (no need to reinvent the wheel).&lt;br /&gt;
&lt;br /&gt;
You can support the ‘twl4030’ in Linux is via a kernel module, which is the way you can access it directly via /dev/twl4030. The TPS65950 talks to the OMAP chip via I2C bus.&lt;br /&gt;
&lt;br /&gt;
Save both files in the same directory then build&lt;br /&gt;
&lt;br /&gt;
twl4030-madc.h&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 /* &lt;br /&gt;
 * include/linux/i2c/twl4030-madc.h &lt;br /&gt;
 * &lt;br /&gt;
 * TWL4030 MADC module driver header &lt;br /&gt;
 * &lt;br /&gt;
 * Copyright (C) 2008 Nokia Corporation &lt;br /&gt;
 * Mikko Ylinen &amp;lt;mikko.k.ylinen@...&amp;gt; &lt;br /&gt;
 * &lt;br /&gt;
 * This program is free software; you can redistribute it and/or &lt;br /&gt;
 * modify it under the terms of the GNU General Public License &lt;br /&gt;
 * version 2 as published by the Free Software Foundation. &lt;br /&gt;
 * &lt;br /&gt;
 * This program is distributed in the hope that it will be useful, but &lt;br /&gt;
 * WITHOUT ANY WARRANTY; without even the implied warranty of &lt;br /&gt;
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU &lt;br /&gt;
 * General Public License for more details. &lt;br /&gt;
 * &lt;br /&gt;
 * You should have received a copy of the GNU General Public License &lt;br /&gt;
 * along with this program; if not, write to the Free Software &lt;br /&gt;
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA &lt;br /&gt;
 * 02110-1301 USA &lt;br /&gt;
 * &lt;br /&gt;
 */ &lt;br /&gt;
 #ifndef _TWL4030_MADC_H &lt;br /&gt;
 #define _TWL4030_MADC_H &lt;br /&gt;
 struct twl4030_madc_conversion_method { &lt;br /&gt;
        u8 sel; &lt;br /&gt;
        u8 avg; &lt;br /&gt;
        u8 rbase; &lt;br /&gt;
        u8 ctrl; &lt;br /&gt;
 }; &lt;br /&gt;
 #define TWL4030_MADC_MAX_CHANNELS 16 &lt;br /&gt;
 struct twl4030_madc_request { &lt;br /&gt;
        u16 channels; &lt;br /&gt;
        u16 do_avg; &lt;br /&gt;
        u16 method; &lt;br /&gt;
        u16 type; &lt;br /&gt;
        int active; &lt;br /&gt;
        int result_pending; &lt;br /&gt;
        int rbuf[TWL4030_MADC_MAX_CHANNELS]; &lt;br /&gt;
        void (*func_cb)(int len, int channels, int *buf); &lt;br /&gt;
 }; &lt;br /&gt;
 enum conversion_methods { &lt;br /&gt;
        TWL4030_MADC_RT, &lt;br /&gt;
        TWL4030_MADC_SW1, &lt;br /&gt;
        TWL4030_MADC_SW2, &lt;br /&gt;
        TWL4030_MADC_NUM_METHODS &lt;br /&gt;
 }; &lt;br /&gt;
 enum sample_type { &lt;br /&gt;
        TWL4030_MADC_WAIT, &lt;br /&gt;
        TWL4030_MADC_IRQ_ONESHOT, &lt;br /&gt;
        TWL4030_MADC_IRQ_REARM &lt;br /&gt;
 }; &lt;br /&gt;
 #define TWL4030_MADC_CTRL1	 0x00 &lt;br /&gt;
 #define TWL4030_MADC_CTRL2	 0x01 &lt;br /&gt;
 #define TWL4030_MADC_RTSELECT_LSB	0x02 &lt;br /&gt;
 #define TWL4030_MADC_SW1SELECT_LSB	0x06 &lt;br /&gt;
 #define TWL4030_MADC_SW2SELECT_LSB	0x0A &lt;br /&gt;
 #define TWL4030_MADC_RTAVERAGE_LSB	0x04 &lt;br /&gt;
 #define TWL4030_MADC_SW1AVERAGE_LSB	0x08 &lt;br /&gt;
 #define TWL4030_MADC_SW2AVERAGE_LSB	0x0C &lt;br /&gt;
 #define TWL4030_MADC_CTRL_SW1	 0x12 &lt;br /&gt;
 #define TWL4030_MADC_CTRL_SW2	 0x13 &lt;br /&gt;
 #define TWL4030_MADC_RTCH0_LSB	 0x17 &lt;br /&gt;
 #define TWL4030_MADC_GPCH0_LSB	 0x37 &lt;br /&gt;
 #define TWL4030_MADC_MADCON	 (1&amp;lt;&amp;lt;0)	/* MADC power on */ &lt;br /&gt;
 #define TWL4030_MADC_BUSY	 (1&amp;lt;&amp;lt;0)	/* MADC busy */ &lt;br /&gt;
 #define TWL4030_MADC_EOC_SW	 (1&amp;lt;&amp;lt;1)	/* MADC conversion completion */ &lt;br /&gt;
 #define TWL4030_MADC_SW_START	 (1&amp;lt;&amp;lt;5)      /* MADC SWx start conversion */ &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN0	 (1&amp;lt;&amp;lt;0) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN1	 (1&amp;lt;&amp;lt;1) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN2	 (1&amp;lt;&amp;lt;2) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN3	 (1&amp;lt;&amp;lt;3) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN4	 (1&amp;lt;&amp;lt;4) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN5	 (1&amp;lt;&amp;lt;5) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN6	 (1&amp;lt;&amp;lt;6) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN7	 (1&amp;lt;&amp;lt;7) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN8	 (1&amp;lt;&amp;lt;8) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN9	 (1&amp;lt;&amp;lt;9) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN10	 (1&amp;lt;&amp;lt;10) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN11	 (1&amp;lt;&amp;lt;11) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN12	 (1&amp;lt;&amp;lt;12) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN13	 (1&amp;lt;&amp;lt;13) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN14	 (1&amp;lt;&amp;lt;14) &lt;br /&gt;
 #define	TWL4030_MADC_ADCIN15	 (1&amp;lt;&amp;lt;15) &lt;br /&gt;
 /* Fixed channels */ &lt;br /&gt;
 #define TWL4030_MADC_BTEMP	 TWL4030_MADC_ADCIN1 &lt;br /&gt;
 #define TWL4030_MADC_VBUS	 TWL4030_MADC_ADCIN8 &lt;br /&gt;
 #define TWL4030_MADC_VBKB	 TWL4030_MADC_ADCIN9 &lt;br /&gt;
 #define	TWL4030_MADC_ICHG	 TWL4030_MADC_ADCIN10 &lt;br /&gt;
 #define TWL4030_MADC_VCHG	 TWL4030_MADC_ADCIN11 &lt;br /&gt;
 #define	TWL4030_MADC_VBAT	 TWL4030_MADC_ADCIN12 &lt;br /&gt;
 /* BCI related - XXX To be moved elsewhere */ &lt;br /&gt;
 #define TWL4030_BCI_BCICTL1	 0x23 &lt;br /&gt;
 #define	TWL4030_BCI_MESBAT	 (1&amp;lt;&amp;lt;1) &lt;br /&gt;
 #define	TWL4030_BCI_TYPEN	 (1&amp;lt;&amp;lt;4) &lt;br /&gt;
 #define	TWL4030_BCI_ITHEN	 (1&amp;lt;&amp;lt;3) &lt;br /&gt;
 #define TWL4030_MADC_IOC_MAGIC '`' &lt;br /&gt;
 #define TWL4030_MADC_IOCX_ADC_RAW_READ	 _IO(TWL4030_MADC_IOC_MAGIC, 0) &lt;br /&gt;
 struct twl4030_madc_user_parms { &lt;br /&gt;
        int channel; &lt;br /&gt;
        int average; &lt;br /&gt;
        int status; &lt;br /&gt;
        u16 result; &lt;br /&gt;
 }; &lt;br /&gt;
 int twl4030_madc_conversion(struct twl4030_madc_request *conv); &lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
'''Main program'''&lt;br /&gt;
&lt;br /&gt;
 /* Test code for the MADC function&lt;br /&gt;
 *&lt;br /&gt;
 * Hugo Vincent, May 2009&lt;br /&gt;
 */&lt;br /&gt;
 #include &amp;lt;sys/ioctl.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;time.h&amp;gt;&lt;br /&gt;
 typedef uint8_t	 u8;&lt;br /&gt;
 typedef uint16_t	u16;&lt;br /&gt;
 #include &amp;quot;twl4030-madc.h&amp;quot;&lt;br /&gt;
 /* Note: (very weird) the madc driver seems to crash if you've got driver debugging&lt;br /&gt;
 * turned on in your defconfig... */&lt;br /&gt;
 /* Channel numbering:&lt;br /&gt;
 * ADC0-1 : to do with battery charging, not relevant on Overo&lt;br /&gt;
 *   ADC2-7 : general purpose, input range = 0 - 2.5V.&lt;br /&gt;
 *            On Overo, ADC2 seems to read as ~0.4 and ADC7 as ~1.4V (?).&lt;br /&gt;
 *   ADC8 : USB OTG port bus voltage.&lt;br /&gt;
 *   ADC9-11 : more battery charging stuff, not relevant.&lt;br /&gt;
 *   ADC12 : main battery voltage.&lt;br /&gt;
 *           This will be the system 3.3V rail in our case&lt;br /&gt;
 *   ADC13-15: reserved or not relevant.&lt;br /&gt;
 */&lt;br /&gt;
 struct adc_channel {&lt;br /&gt;
        int number;&lt;br /&gt;
        char name[16];&lt;br /&gt;
        float input_range;&lt;br /&gt;
 };&lt;br /&gt;
 struct adc_channel channels[] = {&lt;br /&gt;
        {&lt;br /&gt;
                .number = 2,&lt;br /&gt;
                .name = &amp;quot;ADCIN2&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 3,&lt;br /&gt;
                .name = &amp;quot;ADCIN3&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 4,&lt;br /&gt;
                .name = &amp;quot;ADCIN4&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 5,&lt;br /&gt;
                .name = &amp;quot;ADCIN5&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 6,&lt;br /&gt;
                .name = &amp;quot;ADCIN6&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 7,&lt;br /&gt;
                .name = &amp;quot;ADCIN7&amp;quot;,&lt;br /&gt;
                .input_range = 2.5,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 8,&lt;br /&gt;
                .name = &amp;quot;VBUS_USB_OTG&amp;quot;,&lt;br /&gt;
                .input_range = 7.0,&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
                .number = 12,&lt;br /&gt;
                .name = &amp;quot;VBATT/3.3V_RAIL&amp;quot;,&lt;br /&gt;
                .input_range = 6.0,&lt;br /&gt;
        },&lt;br /&gt;
 };&lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
     int d = open(&amp;quot;/dev/twl4030-madc&amp;quot;, O_RDWR | O_NONBLOCK);&lt;br /&gt;
     if (d == -1)&lt;br /&gt;
     {&lt;br /&gt;
         printf(&amp;quot;could not open device /dev/twl4030-madc \n&amp;quot;);&lt;br /&gt;
         exit(EXIT_FAILURE);&lt;br /&gt;
     }&lt;br /&gt;
     struct twl4030_madc_user_parms *par;&lt;br /&gt;
     par = malloc(sizeof(struct twl4030_madc_user_parms));&lt;br /&gt;
     int j;&lt;br /&gt;
     for (j = 0; j &amp;lt; (sizeof(channels)/sizeof(struct adc_channel)); j++)&lt;br /&gt;
     {&lt;br /&gt;
         memset(par, 0, sizeof(struct twl4030_madc_user_parms));&lt;br /&gt;
         par-&amp;gt;channel = channels[j].number;&lt;br /&gt;
         int ret = ioctl(d, TWL4030_MADC_IOCX_ADC_RAW_READ, par);&lt;br /&gt;
         float result = ((unsigned int)par-&amp;gt;result) / 1024.f;/* 10 bit ADC -&amp;gt; 1024 */&lt;br /&gt;
         if (ret == 0 &amp;amp;&amp;amp; par-&amp;gt;status != -1)&lt;br /&gt;
         {&lt;br /&gt;
         printf(&amp;quot;%s (channel %d): %f\n&amp;quot;, channels[j].name, channels[j].number,result * channels[j].input_range);  &lt;br /&gt;
         }&lt;br /&gt;
         else&lt;br /&gt;
         {&lt;br /&gt;
             if (par-&amp;gt;status == -1)&lt;br /&gt;
             {&lt;br /&gt;
                 printf(&amp;quot;Channel %d (%s) timed out!\n&amp;quot;, j, channels[j].name);&lt;br /&gt;
                 printf(&amp;quot;ERROR\n&amp;quot;);&lt;br /&gt;
                 exit(EXIT_FAILURE);&lt;br /&gt;
             }&lt;br /&gt;
         }&lt;br /&gt;
     }	&lt;br /&gt;
     return 0;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
compile it&lt;br /&gt;
&lt;br /&gt;
gcc –o madc madc.c&lt;br /&gt;
&lt;br /&gt;
 root@overo:~# ./madc&lt;br /&gt;
 ADCIN2 (channel 2): 0.673828&lt;br /&gt;
 ADCIN3 (channel 3): 0.087891&lt;br /&gt;
 ADCIN4 (channel 4): 0.612793&lt;br /&gt;
 ADCIN5 (channel 5): 0.090332&lt;br /&gt;
 ADCIN6 (channel 6): 0.341797&lt;br /&gt;
 ADCIN7 (channel 7): 1.374512&lt;br /&gt;
 VBUS_USB_OTG (channel 8): 5.154297&lt;br /&gt;
 VBATT/3.3V_RAIL (channel 12): 3.275391&lt;br /&gt;
 root@overo:~#&lt;br /&gt;
&lt;br /&gt;
when using the ADCs you may/will need to scale values.&lt;br /&gt;
To connect up circuits running at higher than 2.5V you will need to use a voltage divider (resistors)&lt;br /&gt;
&lt;br /&gt;
Vincent, H. (2009) ADC Code Example – Help with Overo ADC. http://old.nabble.com/Re%3A-Help-with-Overo-ADC-td24174607.html &lt;br /&gt;
&lt;br /&gt;
TI TPS65950 Integrated Power Management/Audio Codec Data Manual http://focus.ti.com/lit/ds/symlink/tps65950.pdf&lt;br /&gt;
&lt;br /&gt;
TI TPS65950 OMAP Power Management and System Companion Device Version G Technical Reference Manual http://focus.ti.com/lit/ug/swcu050g/swcu050g.pdf&lt;/div&gt;</summary>
		<author><name>Bart</name></author>	</entry>

	</feed>