Skip to main content
skill CX Codex

bus-drivers-i2c-spi — Claude Code skill: I2C and SPI drivers

Walks an agent through Linux client drivers for I2C and SPI sensors and PMICs: registration, regmap, device tree binding.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add mohitmishra786/low-level-dev-skills --skill bus-drivers-i2c-spi -a claude-code
Open on GitHub

What bus-drivers-i2c-spi does

This skill guides an agent through Linux client drivers on the I2C and SPI buses. It ships working templates: an i2c_driver with probe, of_device_id and i2c_device_id; a raw transfer built from two i2c_msg entries, one writing the register address and one reading the value back; an spi_driver that sets spi->mode and spi->bits_per_word before spi_setup. A separate section covers regmap — config with reg_bits, val_bits and max_register, then regmap_read, regmap_write and regmap_update_bits.

There is a troubleshooting table mapping symptoms to causes. -EREMOTEIO means a NACK, usually a wrong address, so run i2cdetect and check the reg value in the device tree. A wrong SPI mode points at a CPOL/CPHA mismatch against the datasheet. -EPROBE_DEFER shows up when a regulator or clock supplier is not ready yet. A regmap -EIO often means the register and value widths are swapped.

For debugging the skill lists i2cdetect -y 1, i2cdump -y 1 0x48 and reading the device name under /sys/bus/i2c/devices/. You invoke it from the agent as /bus-drivers-i2c-spi followed by the task. Platform MMIO drivers are out of scope here — those live in the separate device-drivers skill.

What it helps with

  • write an I2C client driver for a sensor or PMIC
  • move bare-metal SPI register reads into a kernel driver
  • set up regmap for multi-byte register access
  • track down why a transfer fails with -EREMOTEIO
  • bind a bus device through compatible in the device tree

Example prompts for the agent

  • /bus-drivers-i2c-spi write a regmap-based driver for an I2C PMIC at 0x58
  • /bus-drivers-i2c-spi add an spi_driver for the sensor, SPI_MODE_0, 8 bits per word
  • /bus-drivers-i2c-spi why does probe return -EREMOTEIO on i2c-1?

How to install bus-drivers-i2c-spi

1Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill bus-drivers-i2c-spi -a claude-code

2Manually: put the files in place

~/.claude/skills/bus-drivers-i2c-spi/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/bus-drivers-i2c-spi/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about bus-drivers-i2c-spi

How do I install bus-drivers-i2c-spi in Claude?

Run npx skills add mohitmishra786/low-level-dev-skills --skill bus-drivers-i2c-spi -a claude-code. The skill file then sits at ~/.claude/skills/bus-drivers-i2c-spi/SKILL.md.

What does bus-drivers-i2c-spi do?

It guides the agent through Linux I2C and SPI client drivers: driver registration, transfers via i2c_transfer and spi_sync, regmap usage, and device tree binding. It also includes a table of common failures and their causes.

How is it different from the device-drivers skill?

device-drivers covers platform MMIO drivers, IRQ, DMA and power management. This one is only about clients on the I2C and SPI buses.

Source text

SKILL.md · MIT
---
name: bus-drivers-i2c-spi
description: I2C and SPI bus driver skill for Linux client drivers. Use when writing i2c_driver or spi_driver, register access over bus, DMA SPI transfers, or ACPI/DT client binding. Activates on queries about i2c_client, spi_driver, regmap I2C, SPI transfer, or Linux I2C SPI subsystem.
---

# Bus Drivers (I2C and SPI)

## Purpose

Guide agents through Linux I2C and SPI **client** drivers: bus registration, `i2c_transfer` / `spi_sync`, regmap abstraction, DT `compatible` on bus children, and probe patterns — complementing platform MMIO drivers in `skills/kernel/device-drivers`.

## When to Use

- Sensor or PMIC on I2C/SPI bus
- Converting bare-metal SPI register reads to kernel driver
- Using `regmap` for multi-byte register access
- Debugging `-EREMOTEIO` or missing ACK

## Workflow

### 1. I2C client driver

```c
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>

static int my_probe(struct i2c_client *client)
{
    struct regmap *map;

    map = devm_regmap_init_i2c(client, &my_regmap_config);
    if (IS_ERR(map))
        return PTR_ERR(map);

    dev_info(&client->dev, "probed at 0x%02x\n", client->addr);
    return 0;
}

static const struct of_device_id my_of_id[] = {
    { .compatible = "vendor,sensor" },
    { }
};
MODULE_DEVICE_TABLE(of, my_of_id);

static const struct i2c_device_id my_id[] = {
    { "mysensor", 0 },
    { }
};
MODULE_DEVICE_TABLE(i2c, my_id);

static struct i2c_driver my_driver = {
    .probe    = my_probe,
    .remove   = my_remove,
    .driver   = { .name = "mysensor", .of_match_table = my_of_id },
    .id_table = my_id,
};
module_i2c_driver(my_driver);
```

DT child:

```dts
i2c1 {
    sensor@48 {
        compatible = "vendor,sensor";
        reg = <0x48>;
    };
};
```

### 2. Raw I2C transfer

```c
u8 reg = 0x0F, val;
struct i2c_msg msgs[] = {
    { .addr = client->addr, .flags = 0,       .len = 1, .buf = &reg },
    { .addr = client->addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
};
ret = i2c_transfer(client->adapter, msgs, 2);
```

### 3. SPI driver

```c
static int spi_probe(struct spi_device *spi)
{
    spi->mode = SPI_MODE_0;
    spi->bits_per_word = 8;
    spi_setup(spi);

    struct spi_transfer t = {
        .tx_buf = tx,
        .rx_buf = rx,
        .len    = len,
    };
    struct spi_message m;
    spi_message_init(&m);
    spi_message_add_tail(&t, &m);
    return spi_sync(spi, &m);
}

static struct spi_driver spi_drv = {
    .probe  = spi_probe,
    .driver = { .name = "my-spi", .of_match_table = my_of_match },
};
module_spi_driver(spi_drv);
```

### 4. regmap (preferred for register maps)

```c
static const struct regmap_config my_regmap_config = {
    .reg_bits   = 8,
    .val_bits   = 8,
    .max_register = 0x7F,
};

regmap_read(map, REG_STATUS, &val);
regmap_write(map, REG_CTRL, CTRL_ENABLE);
regmap_update_bits(map, REG_CTRL, MASK, ENABLE);
```

### 5. Debug

```bash
i2cdetect -y 1
i2cdump -y 1 0x48
cat /sys/bus/i2c/devices/i2c-1/1-0048/name
```

### 6. Agent usage

```
/bus-drivers-i2c-spi Write regmap-based driver for I2C PMIC at 0x58
```

## Common Problems

| Symptom | Cause | Fix |
|---------|-------|-----|
| `-EREMOTEIO` | NACK — wrong address | `i2cdetect`; check `reg` in DT |
| SPI mode wrong | CPOL/CPHA mismatch | Match datasheet + `spi->mode` |
| Probe defer | Regulator/clock supplier | Return `-EPROBE_DEFER` |
| regmap -EIO | 16-bit vs 8-bit reg | Set `reg_bits`, `val_bits` |
| DMA not used | Small `spi_sync` OK | `spi_sync_transfer` for bulk |

## Related Skills

- `skills/kernel/device-drivers` — IRQ, DMA, PM runtime
- `skills/kernel-dev/device-tree` — bus child nodes
- `skills/baremetal/spi-i2c-baremetal` — register-level protocol
- `skills/kernel-dev/platform-device-model` — driver model parallels
- `skills/kernel-dev/writing-char-drivers` — expose sensor via char dev

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Similar skills

All skills for Programming languages →

From the same set62

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor