Mode d’emploi
- Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
- Consultez le document original pour les outils, identifiants et environnements requis.
- Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill bus-drivers-i2c-spiAvant de commencer
- L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
- Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
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
regmapfor multi-byte register access - Debugging
-EREMOTEIOor missing ACK
Workflow
1. I2C client driver
#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:
i2c1 {
sensor@48 {
compatible = "vendor,sensor";
reg = <0x48>;
};
};2. Raw I2C transfer
u8 reg = 0x0F, val;
struct i2c_msg msgs[] = {
{ .addr = client->addr, .flags = 0, .len = 1, .buf = ® },
{ .addr = client->addr, .flags = I2C_M_RD, .len = 1, .buf = &val },
};
ret = i2c_transfer(client->adapter, msgs, 2);3. SPI driver
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)
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
i2cdetect -y 1
i2cdump -y 1 0x48
cat /sys/bus/i2c/devices/i2c-1/1-0048/name6. Agent usage
/bus-drivers-i2c-spi Write regmap-based driver for I2C PMIC at 0x58Common 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 runtimeskills/kernel-dev/device-tree— bus child nodesskills/baremetal/spi-i2c-baremetal— register-level protocolskills/kernel-dev/platform-device-model— driver model parallelsskills/kernel-dev/writing-char-drivers— expose sensor via char dev


