Разговор с устройством I2C без микроконтроллера в Linux - PullRequest
0 голосов
/ 11 ноября 2018

Если я не хочу использовать Raspberry или Arduino, как я могу получить доступ к шине I2C для связи с устройством. Я вижу много примеров для малины и много для Arduino, но ни один из них не использует код, который показан ниже. Код ниже проверяет и использует struct i2c_driver. Код также инициализируется в ядре с module_init:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/videodev2.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/log2.h>

#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-subdev.h>
#include <media/soc_camera.h>

#include "adv7403_regs.h"

#define DRIVER_NAME "adv7403"

struct adv7403_state {
          struct v4l2_subdev subdev;
};

static __devinit int adv7403_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
{
          struct adv7403_state *state;
          int ret;

          /* Check if the adapter supports the needed features */
          if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                    return -EIO;

          v4l_info(client, "chip found @ 0x%02x (%s)\n",
                              client->addr << 1, client->adapter->name);

          state = kzalloc(sizeof(struct adv7403_state), GFP_KERNEL);
          if (state == NULL) {
                    ret = -ENOMEM;
                    goto err;
          }
        else{
                    printk(KERN_ERR DRIVER_NAME ": Detected %d\n");
          }

err:
          printk(KERN_ERR DRIVER_NAME ": Failed to probe: %d\n", ret);
          return ret;
}


static __devexit int adv7403_remove(struct i2c_client *client)
{
          struct v4l2_subdev *sd = i2c_get_clientdata(client);

          v4l2_device_unregister_subdev(sd);
          return 0;
}

static const struct i2c_device_id adv7403_id[] = {
          {DRIVER_NAME, 0},
          {},
};

MODULE_DEVICE_TABLE(i2c, adv7403_id);

static struct i2c_driver adv7403_driver = {
          .driver = {
                    .owner          = THIS_MODULE,
                    .name          = DRIVER_NAME,
          },
        .probe                    = adv7403_probe,
        .remove                    = adv7403_remove,
          .id_table          = adv7403_id
};

static int __init adv7403_mod_init(void)
{
          printk(" ADV7403 Video Decoder Device Driver inserted to kernel \n");
          return i2c_add_driver(&adv7403_driver);
}

static void __exit adv7403_mod_exit(void)
{
        printk(" ADV7403 Video Decoder Device Driver removed from kernel \n");
          i2c_del_driver(&adv7403_driver);
}

module_init(adv7403_mod_init);
module_exit(adv7403_mod_exit);

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Сначала вы должны зарегистрировать драйвер шины I2C, чтобы общаться с клиентами I2C.

Это не драйвер шины (адаптера), а драйвер чипа (клиента). Который при регистрации просто вызывает функцию probe(), которая проверяет, присутствует ли клиент I2C.

В этом драйвере нет других функций, например, обратные вызовы, зарегистрированные на уровне ядра I2C, которые используются для доступа к HW-регистрам на чипе, Так какова цель этого драйвера?

0 голосов
/ 14 ноября 2018

Существует (по-видимому) способ использования python и либо последовательного порта (через оптоизоляторы), либо параллельного порта для формирования шины I2C pyi2c

Я понятия не имею, работает ли библиотека - однако я думаю, что она удовлетворяет требованию. Каждый хост Linux имеет как минимум последовательный порт.

Если имеются только USB-порты, существуют мосты USB-I2C / SPI / UART, созданные FTDI и Silicon Labs, которые поддерживают драйверы в последних ядрах. Вы всегда можете добавить поддержку I2C или SPI позже с помощью этой стратегии.

...