reading ADC channels 1,2,3, touchscreen doesn't work

nils
Hi,

the ADC kernel driver only supports reading on channel 0, so i've made a
kernel module with the source of the ADC driver and changed the channel to
1.

It works if i load the module and do "cat /dev/battery", but then the
touchscreen isn't working, even if i remove the module. I have to reboot to
get it working again.

Heres my source Code for the module. I hope anyone can Help me!
http://uc.pastebin.com/VFr959W1

Errol
If i'm not mistaken then the touch screen uses the other ADC lines.

elucches
Try keeping the name of the mutex (ADC_LOCK), because it is what the
touchscreen module (see s3c2410_ts.c in drivers/input/touchscreen) uses
too, so that the ADC is only accessed by one of them at a time.

nils
If i keep the name ADC_LOCK i have to unexport it at the bottom of the
file.
But even if i do this, this has no effect on the touchscreen-behauviour. It
still won't work together with the ADC.

elucches
This is a silly answer, but if all you want to do is change the channel
just change line 120 in mini2440_adc.c
I'm just starting to look at ways to write a driver that allows one to
select the channel. If I find something I'll post it.

elucches
Attachment: mini2440_adc1.c (4.23 KB)
I've just tried the kernel compiled with the attached file besides the
mini2440_adc.c (just a line in the drivers/char/Makefile needs to be
changed) and now I can read both from channel 0 (/dev/adc, no changes from
the original) and from channel 1 (/dev/adc1). I also attach the little
program to test it (see the note in it if you don't do the test from the
host PC). Hope this helps.
Well, I can't attach more than one file, so here is the test program:

//------------------------------------------------------------------------------





// PROJECT:
//   mini2440 ADC driver test
//
// FILE:
//   readadc.c
//
// PURPOSE:
//   Show ADC readings from the channel selected by the user
//
// FUNCTIONS PROVIDED:
//   -
//
// FUNCTIONS CALLED:
//   -
//
// HISTORY:
//   2010.05.17 Created
//
//------------------------------------------------------------------------------







#include <stdio.h>


//------------------------------------------------------------------------------





// main
//
// DESCRIPTION:
//   Selects ADC channel according to the arguments with which it was
called,
//   takes ADC reading, and shows it on stdout
//
// ARGUMENTS:
//   argc
//     Number of arguments of the user call (the executable file name
//     counts as argument 0)
//   argv
//     Array of pointers to the strings representing the arguments
//
// RETURNED VALUE:
//   int
//     0 if everything OK
//     -1 otherwise
//
// NOTES:
//   1. There has to be a function called main to link with arm-linux-gcc,
and
//   it has to return an int so that there are no warnings
//   2. If this function is called using the touchscreen, the reading will
be -1
//   unless the pen is quickly lifted from the touchscreen after touching
<ret>
//
//------------------------------------------------------------------------------





int main(int argc, char * argv[]) {
  char buffer[30];
  int value,
      fd,
      len;

  if(argc != 2) {
    printf("Usage: %s <adc_ch_no>\n", argv[0]);
    return -1;
  }
  switch(atoi(argv[1])) {
    case 0:
      fd = open("/dev/adc", 0);
      break;
    case 1:
      fd = open("/dev/adc1", 0);
      break;
    default:
      break;
  }
  if(fd < 0) {
    printf("Unable to open ADC device\n");
    return -1;
  }
  len = read(fd, buffer, sizeof buffer - 1);
  if(len > 0) {
    buffer[len] = '\0';
    value = -1;
    sscanf(buffer, "%d", &value);
    printf("Channel %d: %d counts\n", atoi(argv[1]), value);
    close(fd);
    return 0;
  } else {
    printf("Unable to read from ADC device\n");
    close(fd);
    return -1;
  }
}

//------------------------------------------------------------------------------





// END OF FILE
//------------------------------------------------------------------------------

Tom
Hello!

I'm trying to use all ADC channels. I've found that thread and have some
questions. Should I create three different files for all channels
(mini2440_adc1,2,3)? Or maybe there is simpler way to do it? And what about
that Makefile - should I just add one more line "obj-$(CONFIG_MINI2440_ADC)
 += mini2440_adc[1..3].o"? Or just change one (but then i think i will have
only one channel, right?)?

thanks in advance
best regards
Tomasz

Joaci
Hi elucches, 
I could not attach the file in Makefile the file mini2440_adc1 in order to
compile both files... I try do add in the makefile follow:

obj-$(CONFIG_MINI2440_ADC1)  += mini2440_adc1.o 

but doesn't work!!

what changes in the makefile I do to attach both files???

thanks in advance
Joaci

shin
Why after i added in adc_ioctl this line into mini2440_adc.c, i can use
other channel but the touchscreen become not function?

static long adc_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
    //printk("arg=%d\ncmd=%d\n",arg,cmd);
    //printk("arg=%d\ncmd=%d\n",(int)arg,(int)cmd);
       switch((int)cmd)
    {
       case 0:
              adcdev.channel = (int)arg;      
            //printk("adcdev.channel=%d\ncmd=%d",adcdev.channel,cmd);
              break;
       case 1:
              adcdev.prescale = (int)arg;
            //printk("adcdev.prescale=%d\n",adcdev.prescale);
              break;
       default:
              return -EINVAL;
              //printk("default");
              break;   
       }
       return 0;
}