안녕하세요.
매번 올때마다 많은걸 배워가기만 하다가 도저히 모르겠는 문제를 만나서
혼자 낑낑대다가 질문을 올립니다. ㅠㅠ;
이번에 회사에서 s3c2440으로 진행하는 프로젝트가 있는데..
대략 ADC에서 난감함 문제가 발생해서 질문을 드려요... ^^
일단 ADC는 touch가 아닌 일반적인 용도의 ADC를 쓰도록 설계가 되었습니다.
삼성에서 제공한 2440 Test용 firmware(ADS버전)으로 H/w구성에는
이상이 없다는것은 확인 하였습니다.
문제는 리눅스에서 디바이스 드라이버를 만들고 ADC register에 write를 할때
값이 써지지 않는다는데 있습니다.
개발 환경은 linux kernel 소스의 base는 aesop-2440 3차버전의 소스입니다.
그리고 mach-aesop 등을 참고해서 mach-type을 저희 H/W에 맞게 구성을
하였습니다.
리눅스 부팅도 정상적으로 되고 다른 드라이버들도 정상적으로 올라 간것도
확인이 다 되었는데 ADC만 정상동작을 하지 않고 있습니다. 이유는 ADC관련
레지스터에서 값을 읽어오는 것은 되는데 write가 되지 않고 있네요.
제가 해본 삽질은....
1. readl(), writel()을 이용 값을 읽어오고 쓰기.
제가가진 커널의 source에 regs-adc.h 와 regs-timer.h의 source상에서의
차이는 다음과 같습니다.
regs-adc.h
#define S3C2410_ADCREG(x) (x)
regs-timer.h
#define S3C2410_TIMERREG(x) (S3C24XX_VA_TIMER + (x))
즉 타이머를 이용하는 드라이버에서는 readl(S3C2410_TCON)
하면 정상적인 값이 읽히는데 readl(S3C2410_ADCCON)을 하면
밑에서의 어떤분이 올리신것처럼 커널 패닉이 발생하더군요...
그래서 regs-adc.h의 위의 부분에 타이머레지스터 처럼 S3C24XX_VA_ADC를
더하는 것을 추가 했더니 정상적으로 읽히는 것을 확인 하였습니다.
(사실 이것찾아내는것도 한참을 낑낑대다가 사무실의 다른 고수님이 도와주셔서
알았습니다.. ㅠㅠ)
하지만 adc register에 값을 쓰는게 안됩니다..
2. touch screen참고 readl(), writel()
다음으로 해본 것이 touchscreen드라이버를 참고해서 test를 해보았습니다.
regs-adc.h를 원래 설정대로 해놓고 ioremap을 통해서 readl(), writel()을
사용 하더군요. 그대로 실행을 해보았습니다. 역시나 읽히는 것은 잘 되고
쓰는 것은 안됩니다.. ㅠㅠ;;
해서 touchscreen의 Kconfig를 바꿔서 현재 커널에 포함을 시켜보고
touchscreen드라이버의 probe에 ADCCON을 r/w해보았습니다.
역시 read는 되고 write안됩니다.. ㅠㅠ;;
3. map_desc수정
map_desc에 ADC영역을 포함 시킨 후 r/w 테스트를 해보았습니다.
역시나 값은 읽히나 써지지가 않습니다.
4. 기타등등...
ioremap, ioremap_nocache도 써보고, writel() 대신 iowrite32()도 써보고,
부트로더에서도 adc register에 r/w해보기(잘됨..)
adc드라이버에서 timer레지스터에 r/w도 해보았는데, adc드라이버 안에서도
timer register에 r/w는 잘 되는 것으로 보아서는 adc register영역에 write하는것이
뭔가 문제가 있는듯 하다.. 라는게 제가 생각할 수 있는 결론 인것 같습니다.
지금 제가 더 해볼 수 있는 삽질이 뭐가 있을까요?
점검해야 할 사항이나 더 살펴봐야 할 부분이 있다면
고수님들의 조언을 부탁드립니다. ^^;
2440 driver tutorial이 있습니다.
거기에 예제가 있습니다....참고하시기 바랍니다.