Linux: Instantiate from User-Space:Eeprom New_Device

Linux: Instantiate from user-space : eeprom new_device

Use "24c32" instead of "eeprom" when instantiate I2C devices.

# echo 24c32 0x50 > /sys/bus/i2c/devices/i2c-0/new_device

In my board with AT24C02 SPD EEPROM, instantiate AT24C02 on bus 2

# echo 24c02 0x50 > /sys/class/i2c-adapter/i2c-2/new_device

The kernel message shows

[21230.868376] at24 2-0050: 256 byte 24c02 EEPROM, writable, 1 bytes/write
[21230.868423] i2c i2c-2: new_device: Instantiated device 24c02 at 0x50

The directory contains

root@:/sys/bus/i2c/devices/i2c-2/2-0050# ls
2-00500/ driver@ eeprom modalias name power/ subsystem@ uevent

The eeprom file is

root@:/sys/bus/i2c/devices/i2c-2/2-0052# hexdump -C eeprom 
00000000 23 11 0c 03 45 21 00 08 00 60 00 03 02 03 00 00 |#...E!...`......|
00000010 00 00 07 0d f8 0f 00 00 6e 6e 6e 11 00 6e f0 0a |........nnn..n..|
00000020 20 08 00 05 00 f0 2b 34 28 00 78 00 14 3c 00 00 | .....+4(.x..<..|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 16 36 0b 35 |.............6.5|
00000040 16 36 0b 35 00 00 16 36 0b 35 16 36 0b 35 00 00 |.6.5...6.5.6.5..|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000070 00 00 00 00 00 00 9c b5 00 00 00 00 e7 d6 0b e3 |................|
00000080 0f 11 02 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 db 08 |................|
00000100

Reading a 32k i2c eeprom from userland

Done!
It wasn't easy because I could not find documentations anywhere.. but I thought that since the eeprom is 32K, maybe it was "like" a 24c256. But even in that case I found nothing in userspace until I decided to go by instinct.
I studied i2cset source, understood what it did and put it in the code.

Here is the result, which dumps a full i2c 32k eprom from userspace.

Note a full backup and restore utility can be found here:
https://gist.github.com/Zibri/cf8ac0b311301aeeaa8910c7da824bff

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

#define READ_SIZE (256)
#define NB_PAGES (128)

void dump_to_file(const char *output_file_path,
const uint8_t *buffer, const int buffer_length)
{
int output_file = open(output_file_path, O_RDWR|O_APPEND|O_CREAT);
if (output_file < 0) {
printf("Failed opening output file %s\n", output_file_path);
return;
}

write(output_file, buffer, buffer_length);
}

int main(int argc, char *argv[])
{

const char *i2c_device = "/dev/i2c-4";
const int device_address = 0x50;

int file = open(i2c_device, O_RDWR);
if (file < 0) {
printf("Failed opening %s\n", i2c_device);
return 1;
}

if (ioctl(file, I2C_SLAVE, device_address) < 0) {
printf("Failed addressing device at %02X\n", device_address);
close(file);
return 1;
}

int i = 0;

write(file,'\x00\x00',2); // ADDRESS

for (i = 0; i < NB_PAGES; i++) {
char buf[READ_SIZE] = {0};

if (read(file, buf, READ_SIZE) != READ_SIZE) {
printf("Failed reading\n");
close(file);
return 1;
}

dump_to_file(argv[1], buf, READ_SIZE);
}

close(file);

return 0;
}

how to instantiate i2c-mux-gpio driver from users-space

If you're using the Device Tree on your platform, you should have a look at the recent Device Tree Overlay mechanism which was merged. It also to load additional fragments of Device Tree at runtime.

adding i2c client devices on x86_64

Since you have an ACPI-enabled platform the best approach is to provide the ASL excerpts for given devices.

Because of Intel Galileo platform for IoT the Atmel 24 series EEPROM has got its own ACPI ID and an excerpt will be simple:

DefinitionBlock ("at24.aml", "SSDT", 5, "", "AT24", 1)
{
External (_SB_.PCI0.I2C2, DeviceObj)

Scope (\_SB.PCI0.I2C2)
{
Device (EEP0) {
Name (_HID, "INT3499")
Name (_DDN, "Atmel AT24 compatible EEPROM")
Name (_CRS, ResourceTemplate () {
I2cSerialBusV2 (
0x0057, // I2C Slave Address
ControllerInitiated,
400000, // Bus speed
AddressingMode7Bit,
"\\_SB.PCI0.I2C2", // Link to ACPI I2C host controller
0
)
})

Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"size", 1024},
Package () {"pagesize", 32},
}
})
}
}
}

Note, the size property is being added in a pending patch series (patches add eeprom "size" property and add support to fetch eeprom device property "size").

Note, the address width is 8-bit as hard coded for now. In case you need to have 16-bit you need to create a similar patches as mentioned above.

For LTC2990 power monitor you need the following excerpt:

DefinitionBlock ("ltc2990.aml", "SSDT", 5, "", "PMON", 1)
{
External (\_SB_.PCI0.I2C2, DeviceObj)

Scope (\_SB.PCI0.I2C2)
{
Device (PMON)
{
Name (_HID, "PRP0001")
Name (_DDN, "Linear Technology LTC2990 power monitor")
Name (_CRS, ResourceTemplate () {
I2cSerialBus (
0x4c, // Bus address
ControllerInitiated, // Don't care
400000, // Fast mode (400 kHz)
AddressingMode7Bit, // 7-bit addressing
"\\_SB.PCI0.I2C2", // I2C host controller
0 // Must be 0
)
})

Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () {"compatible", "lltc,ltc2990"},
}
})
}
}
}

Note, unfortunately there is no compatible string in the driver, so, one needs to add it like it's done here.

In the examples above \\_SB.PCI0.I2C2 is an absolute path to the I2C host controller.

How to get those files applied:

  • first of all, create a folder
mkdir -p kernel/firmware/acpi
  • save files under names mentioned in the DefinitionBlock() macro in that folder
  • create the uncompressed cpio archive and concatenate the original initrd on top:
find kernel | cpio -H newc --create > /boot/instrumented_initrd
cat /boot/initrd >> /boot/instrumented_initrd

More details are available in SSDT Overlays.

The other examples and description of the idea behind can be found on meta-acpi GitHub page, some materials from which are copied here.

eeprom : uevent generated infinite times in linux kernel 4.4.0

Disabled i2c-core debugging(CONFIG_I2C_DEBUG_CORE not set) in kernel configuration.



Related Topics



Leave a reply



Submit