[SOLVED] How to reverse sda/scl pins in s3c2410 i2c drivers?
Linux - Embedded & Single-board computerThis forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Introduction to Linux - A Hands on Guide
This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.
Click Here to receive this Complete Guide absolutely free.
How to reverse sda/scl pins in s3c2410 i2c drivers?
Hi. I'm working with a custom s3c2410 board, and I have an interesting delima. The company I work for had this board made a long time ago, and they based everything on the 2.4.18 kernel from the old Mizi Linux. I've been working with getting everything working on a standard 2.6 kernel. So far so good - I've had success in many areas, but I'm stuck on one major problem.
The original designers opted to not use the RTC internal to the s3c2410. Instead, they attached an s35390a to the i2c bus. The problem is that when they wired it up, they messed up and swapped the SDA and SCL lines. So when I try to load the driver, of course it can't find the device at all. I need a software solution - cutting the lines on the PCB and rewiring them is not an option, due to the vast quantity already produced.
Now the old 2.4 kernel appears to be working ok, but they did not use any standard driver. They hacked apart the rtc driver and put their own codes in. Not acceptable in my book. I should just be able to use the standard s35390a driver under 2.6. I haven't been able to follow their hacks well enough to figure out how they dealt with the swapped lines. Not sure if it would even help anyway.
So the question is, how do I tell the i2c bus that I have a device with swapped pins? It is the only device on the bus, so I'm ok swapping the i2c pins themselves.
I found in /arch/arm/plat/s3c24xx/setup-i2c.c where the default gpios are configured for the i2c bus:
Ok, based on your recomendation, I tried swapping the pins on my test board and leaving the i2c driver alone. It still doesn't work, so I think there is something else going on here with the s3c2410-i2c driver, or with my external rtc.
I've been using the i2ctools from the lmsensors project to help with testing. Specifically, i2cdetect and i2cdump.
The good news is that I get the same results from i2cdetect using either the software swap (as posted above), or the phsical hardware swap. So, I would guess that the software swap will indeed work once I figure the rest out.
The bad news is now that with the pins wrong, i2cdetect completes but shows no results. With the pins correct, i2cdetect hangs and immediately starts throwing this error repeatedly:
s3c-i2c s3c2410-i2c: cannot get bus (error -110)
One other thing - the RTC chip is labeled S35390, but the only linux driver is for S35390A. I can't even find a datasheet on S35390, only the "A" model. I assume that the difference isn't important for my purposes, but who knows. At any rate, the driver doesn't even load because of the i2c problems, so I don't think it's important.
The only thing I could find on google about the error -100 is an old patch to openmoko - which basically implemented suspend/resume functions. I found that similar code is already implemented in the current 2.6.36 kernel I'm using, but it only invokes with CONFIG_PM enabled (power management). I re-build my kernel to enable CONFIG_PM and tried again, but got the same results.
I'm starting to wonder if the device is wired backwards because the cpu is hooked up backwards too, so really it's wired correctly. (two wrongs make a right in some countries...) So maybe it's not backwards at all and I'm just having driver issues.
Anyone know if the s35390 is a different animal than the s35390a? The only drivers I see anywhere are for the "a" model, so that's what I'm trying to use.
Either way, wouldn't i2cdetect find something out there even if I had the wrong driver?
I've been researching all I can about i2c and so far it looks like I'm doing it right, so I'm not sure what to try next.
Basically, I disabled the i2c bus drivers and then used the /sys/class/gpio interface to toggle the pins while testing the output with a logic probe on the lines to my rtc. Using this method, I was able to confirm the pins were indeed swaped (SDA on GPE14 and SCL on GPE15). While this wasn't the key to the solution, I thought I would post this simple techinique in case others may find it useful.
What actually solved my problem was switching from the s3c-i2c driver to the generic i2c-gpio driver. I tried this on a whim without thinking much would come of it, but it worked! Maybe someone can shed light on why. I tried the same pin and delay settings in the s3c-i2c driver without success. No changes were necessary to the rtc configuration. Here is my device setup for the i2c-gpio driver:
What you do here is simply configure the input/output status for GPIO GPE14 and GPE15 (Defined in arch/arm/mach-s3c2410/include/mach/regs-gpio.h), but the actual i2c output is controller by I2C Controller and would not invert SCL/SDA signals at all.
In fact you can't invert the two pins if you are using the hardware controller (it doesn't support it).
The only solution is to use gpio-base emulation as you did(it use the same pins but your data is sent/recv through i2c-bus by kernel, pulling up/down the two pins to emulate i2c output).
That way needs more cpu instructions but since your i2c is a rtc device, that's ok (it only reads once at boot-up and writes to at shut-down).