Как драйвер Linux может делегировать функции другому драйверу (совместно используемое оборудование) - PullRequest
0 голосов
/ 12 июля 2019

Я пишу собственный драйвер ИК-передатчика для lirc на встроенной плате. На плате установлен удлинитель i2c-to-gpio ( FXL6408 ).

Проблема в том, что для моего драйвера требуется только один вывод GPIO (и, следовательно, LIRC), а другие выводы нужны для использования другими приложениями. Как то так:

Driver Connections

Я читал LWM, LDD3 и тонны сайтов о i2c-slave, i2c адаптерах, шинах , pinctrl, gpio, стекировании и т. Д., Но это не так ясно, как делать то, что я хочу:

my-driver необходимо управлять одним выводом на расширителе GPIO, в то же время позволяя другим приложениям управлять другими 7 контактами через /dev/i2c-0.

После это SO предложение было многообещающим, но i2c_new_dummy не удалось, возвращая NULL:

i2cAdaptor = i2c_get_adapter(ECP_I2CBUS); // 1 means i2c-1 bus
if (i2cAdaptor == NULL)
{
    printk("ecp_gpio: Could not acquire i2c adaptor\n");
    return -EBUSY;
}

i2cClient  = i2c_new_dummy(i2cAdaptor, ECP_I2CDEV); // 0x43 - slave address on i2c bus
if (i2cClient == NULL)
{
    printk("ecp_gpio: Could not acquire i2c client\n");
    return -EBUSY;
}

if ( (rc = i2c_smbus_write_byte(i2cClient, 0xF0)) < 0)
{
    printk("ecp_gpio: Error writing byte - error %d", rc);
    return -EIO;
}

Как правильно подключить сантехнику для достижения того, чего я хочу?

Информация об ОС:

# uname -a
Linux ecp 4.4.127-1.el6.elrepo.i686 #1 SMP Sun Apr 8 09:44:43 EDT 2018 i686 i686 i386 GNU/Linux

1 Ответ

0 голосов
/ 14 июля 2019

Попробовав много разных вещей, я нашел один, который работает.Я не знаю, является ли это «правильным способом», но это работает.

Вместо того, чтобы пытаться создать фиктивного клиента, просто вызовите функции i2c_xx напрямую.Итак, код выглядит так:

i2cAdaptor = i2c_get_adapter(ECP_I2CBUS); // 1 means i2c-1 bus etc
if (i2cAdaptor == NULL)
{
    printk("ecp_gpio: Could not acquire i2c adaptor\n");
    return -EBUSY;
}


union i2c_smbus_data data;

data.byte = 0xF0;

if ((rc = i2c_smbus_xfer(ecpHardware.i2cAdaptor, ECP_I2CDEV, 0, I2C_SMBUS_WRITE, 0x05, I2C_SMBUS_BYTE_DATA, &data)) < 0)
{
    printk("ecp_gpio: i2c_smbus_xfer failed: %d\n", rc);
    return -EIO;
}

data.byte = 0xE0;

if ((rc = i2c_smbus_xfer(ecpHardware.i2cAdaptor, ECP_I2CDEV, 0, I2C_SMBUS_WRITE, 0x05, I2C_SMBUS_BYTE_DATA, &data)) < 0)
{
    printk("ecp_gpio: i2c_smbus_xfer failed: %d\n", rc);
    return -EIO;
}
...