Bug 189914 - i2c(8) utility does not work on Raspberry Pi
Summary: i2c(8) utility does not work on Raspberry Pi
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: unspecified
Hardware: arm Any
: --- Affects Many People
Assignee: Ian Lepore
URL:
Keywords: needs-patch, needs-qa
Depends on:
Blocks:
 
Reported: 2014-05-18 19:10 UTC by Vadim Zaigrin
Modified: 2019-07-08 14:36 UTC (History)
8 users (show)

See Also:
koobs: mfc-stable10?
koobs: mfc-stable11?


Attachments
file.txt (7.87 KB, text/plain)
2014-05-18 19:10 UTC, Vadim Zaigrin
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vadim Zaigrin 2014-05-18 19:10:00 UTC
Hi

i2c(8) utility does not work on Raspberry Pi.

It uses syscall ioctl I2CSTART, I2CSTOP, I2CRSTCARD, I2CWRITE and I2CREAD.
This syscalls try to call iicbus interfaces iicbus_start, iicbus_stop, iicbus_reset, iicbus_write and iicbus_read.
But there is only iicbus_transfer interface in iicbus device.
Interface iicbus_transfer is used by syscall ioctl I2CRDWR.

Fix: I have corrected source code of the i2c(8) utility to work on Raspberry Pi.
The patch to the original source code and the updated source code are available here: https://github.com/vzaigrin/newi2c

i2c.c.patch is a patch for original source code of the i2c.c
newi2c.c is an updated source code of the i2c.c

Hope this can help

Patch attached with submission follows:
Comment 1 Luiz Otavio O Souza,+55 (14) 99772-1255 freebsd_committer 2014-05-20 21:11:11 UTC
Responsible Changed
From-To: freebsd-arm->loos

I'll take it.
Comment 2 Lars Engels freebsd_committer 2014-07-15 21:22:40 UTC
Hi Luiz,

have you already found time to look into this?
Comment 3 Luiz Otavio O Souza,+55 (14) 99772-1255 freebsd_committer 2014-07-16 18:47:17 UTC
(In reply to Lars Engels from comment #2)
> Hi Luiz,
> 
> have you already found time to look into this?

Yes Lars, but unfortunately this patch is doing some evil stuff to make the search work:

@@ -154,6 +160,10 @@
                }
        }
 
+/* To read from non existing device we need first to disable console messages */
+       mute = 1;
+       sysctlbyname("kern.consmute", NULL, NULL, &mute, sizeof(mute) );
+
        printf("Scanning I2C devices on %s: ", dev);
        for (i = 1; i < 127; i++) {

It can also lock up the bus and/or devices while scanning the bus (you need to write at least two bytes or some devices will be left in an unknown state at the end of scanning):

+       uint8_t offset, buf;
[...]
-               cmd.slave = i << 1;
-               cmd.last = 1;
-               cmd.count = 0;
-               error = ioctl(fd, I2CRSTCARD, &cmd);
-               if (error)
-                       goto out;
+               offset = 0;
+               msg[0].slave = i;
+               msg[0].flags = !IIC_M_RD;
+               msg[0].len = sizeof( offset );
+               msg[0].buf = &offset;
+               msg[1].slave = i;
+               msg[1].flags = IIC_M_RD;
+               msg[1].len = sizeof( buf );
+               msg[1].buf = &buf;
+               rdwr.msgs = msg;
+               rdwr.nmsgs = 2;
+               if ( ioctl(fd, I2CRDWR, &rdwr) >= 0 )  {
+                 printf("%x ", i);
+                 found = 1;
+               }

It also replace all the old methods which still works for a few controllers.

So i'll try to keep the old behaviour while adding support to this type of i2c controllers. I have scanning working but it needs more work on the other options.

I'm also considering a few changes from the patch at: http://www.phisch.org/website/glxiic/

Luiz
Comment 4 Lars Engels freebsd_committer 2014-07-16 19:09:20 UTC
Thank you for the feedback, Luiz.
Comment 5 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:48:21 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Comment 6 Zane C. Bowers-Hadley 2018-07-16 03:05:17 UTC
This is still relevant.

I need it to access the IIC on my UMPC here.
Comment 7 Zane C. Bowers-Hadley 2018-07-16 03:08:35 UTC
Also worth noting it is broken on more than the RPi. 

[root@sheila]0{480,47.0C}/root/bin>uname -a
FreeBSD sheila.vvpn.vvelox.net 11.2-RELEASE FreeBSD 11.2-RELEASE #0 r335510: Fri Jun 22 04:32:14 UTC 2018     root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64

CPU: Intel(R) Atom(TM) x5-Z8350  CPU @ 1.44GHz (1440.00-MHz K8-class CPU)
  Origin="GenuineIntel"  Id=0x406c4  Family=0x6  Model=0x4c  Stepping=4
Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
Features2=0x43d8e3bf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,CX16,xTPR,PDCM,SSE4.1,SSE4.2,MOVBE,POPCNT,TSCDLT,AESNI,RDRAND>
  AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
  AMD Features2=0x101<LAHF,Prefetch>
  Structured Extended Features=0x2282<TSCADJ,SMEP,ERMS,NFPUSG>
  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID
  TSC: P-state invariant, performance statistics

iicbus6: <Philips I2C bus> on ig4iic_acpi6
iic6: <I2C generic I/O> on iicbus6
iicsmb6: <SMBus over I2C bridge> on iicbus6
smbus6: <System Management Bus> on iicsmb6
Comment 8 Kubilay Kocak freebsd_committer freebsd_triage 2018-07-16 04:00:04 UTC
Reset assignee (Luiz, last modified 4+ years), keep Luiz CC'd so someone else can take this if necessary.

Given the age of this issue, it would be great to get (re)confirmation that base i2c(8) in CURRENT, as of today, still doesn't work on arm (RPi)

The current patch apparently (comment 3) needs work, but more precisely, is not in a state ready to commit (needs-patch). An updated patch against CURRENT is required to progress this issue.
Comment 9 Zane C. Bowers-Hadley 2018-07-16 05:41:13 UTC
The i2c util in HEAD still does not work. I've not tried it on a RPi.

See my comment above on what it is currently broken on.

On another note trying the newi2c.c that was linked to seems to give me some issues as well. But it actually works though. the issues with it is outputting it. It uses stderr instead of stdout.
Comment 10 Zane C. Bowers-Hadley 2018-07-16 05:43:06 UTC
Worth noting that currently 11 and HEAD are currently the same in regards to this, from what I am seeing, incase any one is wondering about what I pasted earlier showing 11.
Comment 11 Kyle Evans freebsd_committer 2018-08-09 01:46:44 UTC
CC freebsd-arm@
Comment 12 Jorge Schrauwen 2018-08-21 21:46:13 UTC
Still broken on RPi (Tested on a Raspberry Pi 3B+ with HEAD build about an hour ago)
Comment 13 commit-hook freebsd_committer 2019-05-22 21:06:33 UTC
A commit references this bug:

Author: ian
Date: Wed May 22 21:06:10 UTC 2019
New revision: 348120
URL: https://svnweb.freebsd.org/changeset/base/348120

Log:
  Add a new 'tr' (transfer) mode to i2c(8) to support more i2c controllers.

  Some i2c controller hardware does not provide a way to do individual START,
  REPEAT-START and STOP actions on the i2c bus.  Instead, they can only do
  a complete transfer as a single operation.  Typically they can do either
  START-data-STOP or START-data-REPEATSTART-data-STOP.  In the i2c driver
  framework, this corresponds to the iicbus_transfer method.  In the userland
  interface they are initiated with the I2CRDWR ioctl command.

  These changes add a new 'tr' mode which can be specified with the '-m'
  command line option.  This mode should work on all hardware; when an i2c
  controller driver doesn't directly support the iicbus_transfer method,
  code in the i2c driver framework uses the lower-level START/REPEAT/STOP
  methods to implement the transfer.  After this new mode has gotten some
  testing on various hardware, the 'tr' mode should probably become the
  new default mode.

  PR:		189914

Changes:
  head/usr.sbin/i2c/i2c.8
  head/usr.sbin/i2c/i2c.c
Comment 14 Ian Lepore freebsd_committer 2019-05-22 21:14:23 UTC
BTW, I do plan to MFC the fix for this to 12-stable after it has gotten some testing.  I'll probably merge it to 11-stable as well, but not during the 11.3 code freeze unless someone specifically requests it to be in 11.3 and is willing to do some testing of it there.
Comment 15 commit-hook freebsd_committer 2019-06-23 15:55:46 UTC
A commit references this bug:

Author: ian
Date: Sun Jun 23 15:55:42 UTC 2019
New revision: 349310
URL: https://svnweb.freebsd.org/changeset/base/349310

Log:
  MFC r348120:

  Add a new 'tr' (transfer) mode to i2c(8) to support more i2c controllers.

  Some i2c controller hardware does not provide a way to do individual START,
  REPEAT-START and STOP actions on the i2c bus.  Instead, they can only do
  a complete transfer as a single operation.  Typically they can do either
  START-data-STOP or START-data-REPEATSTART-data-STOP.  In the i2c driver
  framework, this corresponds to the iicbus_transfer method.  In the userland
  interface they are initiated with the I2CRDWR ioctl command.

  These changes add a new 'tr' mode which can be specified with the '-m'
  command line option.  This mode should work on all hardware; when an i2c
  controller driver doesn't directly support the iicbus_transfer method,
  code in the i2c driver framework uses the lower-level START/REPEAT/STOP
  methods to implement the transfer.  After this new mode has gotten some
  testing on various hardware, the 'tr' mode should probably become the
  new default mode.

  PR:		189914

Changes:
_U  stable/12/
  stable/12/usr.sbin/i2c/i2c.8
  stable/12/usr.sbin/i2c/i2c.c
Comment 16 commit-hook freebsd_committer 2019-07-08 14:34:46 UTC
A commit references this bug:

Author: ian
Date: Mon Jul  8 14:34:01 UTC 2019
New revision: 349836
URL: https://svnweb.freebsd.org/changeset/base/349836

Log:
  MFC r348120:

  Add a new 'tr' (transfer) mode to i2c(8) to support more i2c controllers.

  Some i2c controller hardware does not provide a way to do individual START,
  REPEAT-START and STOP actions on the i2c bus.  Instead, they can only do
  a complete transfer as a single operation.  Typically they can do either
  START-data-STOP or START-data-REPEATSTART-data-STOP.  In the i2c driver
  framework, this corresponds to the iicbus_transfer method.  In the userland
  interface they are initiated with the I2CRDWR ioctl command.

  These changes add a new 'tr' mode which can be specified with the '-m'
  command line option.  This mode should work on all hardware; when an i2c
  controller driver doesn't directly support the iicbus_transfer method,
  code in the i2c driver framework uses the lower-level START/REPEAT/STOP
  methods to implement the transfer.  After this new mode has gotten some
  testing on various hardware, the 'tr' mode should probably become the
  new default mode.

  PR:		189914

Changes:
_U  stable/11/
  stable/11/usr.sbin/i2c/i2c.8
  stable/11/usr.sbin/i2c/i2c.c