Added more capabilities checks for I2C

Signed-off-by: Erik Agsjö <erik.agsjo@gmail.com>
This commit is contained in:
Erik Agsjö 2017-02-27 23:40:14 +01:00
parent f0873adea6
commit ea93b203bd
3 changed files with 58 additions and 3 deletions

View File

@ -5,15 +5,31 @@ import (
"gobot.io/x/gobot/gobottest"
"gobot.io/x/gobot/sysfs"
"syscall"
"unsafe"
)
func syscallImpl(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
if (trap == syscall.SYS_IOCTL) && (a2 == sysfs.I2C_FUNCS) {
var funcPtr *uint64 = (*uint64)(unsafe.Pointer(a3))
*funcPtr = sysfs.I2C_FUNC_SMBUS_READ_BYTE | sysfs.I2C_FUNC_SMBUS_READ_BYTE_DATA |
sysfs.I2C_FUNC_SMBUS_READ_WORD_DATA |
sysfs.I2C_FUNC_SMBUS_WRITE_BYTE | sysfs.I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
sysfs.I2C_FUNC_SMBUS_WRITE_WORD_DATA
}
// Let all operations succeed
return 0, 0, 0
}
func initI2CDevice() sysfs.I2cDevice {
fs := sysfs.NewMockFilesystem([]string{
"/dev/i2c-1",
})
sysfs.SetFilesystem(fs)
sysfs.SetSyscall(&sysfs.MockSyscall{})
sysfs.SetSyscall(&sysfs.MockSyscall{
Impl: syscallImpl,
})
i, _ := sysfs.NewI2cDevice("/dev/i2c-1")
return i
}

View File

@ -9,6 +9,7 @@ import (
)
const (
// From /usr/include/linux/i2c-dev.h:
// ioctl signals
I2C_SLAVE = 0x0703
I2C_FUNCS = 0x0705
@ -16,7 +17,15 @@ const (
// Read/write markers
I2C_SMBUS_READ = 1
I2C_SMBUS_WRITE = 0
// From /usr/include/linux/i2c.h:
// Adapter functionality
I2C_FUNC_SMBUS_READ_BYTE = 0x00020000
I2C_FUNC_SMBUS_WRITE_BYTE = 0x00040000
I2C_FUNC_SMBUS_READ_BYTE_DATA = 0x00080000
I2C_FUNC_SMBUS_WRITE_BYTE_DATA = 0x00100000
I2C_FUNC_SMBUS_READ_WORD_DATA = 0x00200000
I2C_FUNC_SMBUS_WRITE_WORD_DATA = 0x00400000
I2C_FUNC_SMBUS_READ_BLOCK_DATA = 0x01000000
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA = 0x02000000
// Transaction types
@ -108,35 +117,59 @@ func (d *i2cDevice) Close() (err error) {
}
func (d *i2cDevice) ReadByte() (val uint8, err error) {
if d.funcs&I2C_FUNC_SMBUS_READ_BYTE == 0 {
return 0, fmt.Errorf("SMBus read byte not supported")
}
var data uint8
err = d.smbusAccess(I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, uintptr(unsafe.Pointer(&data)))
return data, err
}
func (d *i2cDevice) ReadByteData(reg uint8) (val uint8, err error) {
if d.funcs&I2C_FUNC_SMBUS_READ_BYTE_DATA == 0 {
return 0, fmt.Errorf("SMBus read byte data not supported")
}
var data uint8
err = d.smbusAccess(I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, uintptr(unsafe.Pointer(&data)))
return data, err
}
func (d *i2cDevice) ReadWordData(reg uint8) (val uint16, err error) {
if d.funcs&I2C_FUNC_SMBUS_READ_WORD_DATA == 0 {
return 0, fmt.Errorf("SMBus read word data not supported")
}
var data uint16
err = d.smbusAccess(I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, uintptr(unsafe.Pointer(&data)))
return data, err
}
func (d *i2cDevice) WriteByte(val uint8) (err error) {
if d.funcs&I2C_FUNC_SMBUS_WRITE_BYTE == 0 {
return fmt.Errorf("SMBus write byte not supported")
}
err = d.smbusAccess(I2C_SMBUS_WRITE, val, I2C_SMBUS_BYTE, uintptr(0))
return err
}
func (d *i2cDevice) WriteByteData(reg uint8, val uint8) (err error) {
if d.funcs&I2C_FUNC_SMBUS_WRITE_BYTE_DATA == 0 {
return fmt.Errorf("SMBus write byte data not supported")
}
var data = val
err = d.smbusAccess(I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, uintptr(unsafe.Pointer(&data)))
return err
}
func (d *i2cDevice) WriteWordData(reg uint8, val uint16) (err error) {
if d.funcs&I2C_FUNC_SMBUS_WRITE_WORD_DATA == 0 {
return fmt.Errorf("SMBus write word data not supported")
}
var data = val
err = d.smbusAccess(I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, uintptr(unsafe.Pointer(&data)))
return err

View File

@ -13,7 +13,9 @@ type SystemCaller interface {
type NativeSyscall struct{}
// MockSyscall represents the mock Syscall
type MockSyscall struct{}
type MockSyscall struct {
Impl func(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
}
var sys SystemCaller = &NativeSyscall{}
@ -34,5 +36,9 @@ func (sys *NativeSyscall) Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err
// Syscall implements the SystemCaller interface
func (sys *MockSyscall) Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) {
return 0, 0, 0
if sys.Impl != nil {
return sys.Impl(trap, a1, a2, a3)
} else {
return 0, 0, 0
}
}