Armadilloフォーラム

Armadillo-IoT アドオンモジュール DA00 2個使い

mkohei1122

2015年8月27日 13時38分

森と申します。

Armadillo-IoTに絶縁デジタル入出力/アナログ入力アドオンモジュール DA002個を
アドオン用のコネクタCON1, CON2にそれぞれ実装し、各2ポートのアナログ入力×2
の合計4ポートのアナログ入力を検討しております。

下記のマニュアルV2.01を拝見しますと、カーネル3.1.4では、アナログ入力は、
IIO デバイスとして実装され、デバイスを認識した順番で iio:deviceN (N は'0'からの連番)
となるとあります。

http://manual.atmark-techno.com/armadillo-iot/armadillo-iotg-std_produc…

そこで、認識の順番がポイントとなりますが、標準の状態においては、必ず
CON1、CON2の順に認識されて、CON1: iio:deviceN、CON2: iio:deviceN+1
となるのでしょうか。

認識順がランダムですと、間違ったアナログ入力となってしまい問題となって
しまいます。
なお、IIO デバイス名(name)で区別しても、同じボードで"mcp3202"ですので、
区別できません。

回避策等をご指導をいただければ、幸いです。

コメント

中村です。

#ちょっと長いです

> 下記のマニュアルV2.01を拝見しますと、カーネル3.1.4では、アナログ入力は、

カーネル3.14-at2ですよね?

Armadilloのカーネル3.14は出たばかりなので、
まだまだわからないことだらけですが、
勉強を兼ねて探ってみました。

> 認識順がランダムですと、間違ったアナログ入力となってしまい問題となって
> しまいます。
> なお、IIO デバイス名(name)で区別しても、同じボードで"mcp3202"ですので、
> 区別できません。

/dev/iio:deviceN と evices/iio:deviceN の下を探してみましたが、
それらしき情報はなさそうです。(探したりない?)

マニュアルの
8.3.10. ADコンバーター
http://manual.atmark-techno.com/armadillo-iot/armadillo-iotg-std_produc…

に、次の記述があります。
| MCP3202 は、絶縁 IO アドオンモジュールをアドオン
| インターフェース(ベースボード:CON1)に接続した場合は SPI2 に、
| アドオンインターフェース(ベースボード:CON2)に接続した場合は SPI3 に
| 接続されています。

これを頼りにSPIの方から探してみました。
ブート時に
spi_imx imx35-cspi.1: probed
spi_imx imx35-cspi.2: probed
というメッセージが出てます。
これ以外はspiのメッセージはなさそうです。

ブート後、spiデバイスは・・・
# ls /sys/bus/spi/devices/
spi1.0@ spi2.0@

# ls /sys/bus/spi/devices/spi1.0/
driver@ iio:device0/ modalias power/ subsystem@ uevent

# ls /sys/bus/spi/devices/spi2.0/
driver@ iio:device1/ modalias power/ subsystem@ uevent

# cat /sys/bus/spi/devices/spi1.0/modalias
spi:mcp3202

# cat /sys/bus/spi/devices/spi2.0/modalias
spi:mcp3202

これから、
spi1.0 ⇒ iio:device0
spi2.0 ⇒ iio:device1
ということがわります。

そうすると、デバイスファイル(といっていいのかな?)のspi0,spi1と
ハードウェアのSPI2(CON1),SPI3(CON2)の関係がわかれば、
解決ですね。

spiを初期化しているソースを探しました。
linux-3.14-at2/arch/arm/mach-imx/armadillo_iotg_std_extif.c
の次の関数で初期化(登録?)しているようです。

void __init armadillo_iotg_std_extif_init(void)
{
        ....
        if (IS_ENABLED(CONFIG_AIOTG_STD_SPI2)) {
                imx25_add_spi_imx1(&spi1_pdata);
                spi_register_board_info(armadillo_iotg_std_spi1_board_info,
                                        ARRAY_SIZE(armadillo_iotg_std_spi1_board_info));
        }
 
        if (IS_ENABLED(CONFIG_AIOTG_STD_SPI3)) {
                imx25_add_spi_imx2(&spi2_pdata);
                spi_register_board_info(armadillo_iotg_std_spi2_board_info,
                                        ARRAY_SIZE(armadillo_iotg_std_spi2_board_info));
        ....
 
}

この順番で
/sys/bus/spi/devices/spi1.0/
/sys/bus/spi/devices/spi2.0/
になるではないなかぁ~と、思ってます。

これとは別に、
linux-3.14-at2/arch/arm/mach-imx/armadillo_iotg_std_addon/addon_atmark_techno_didoad.c
に、こんなコードもありました。

static struct spi_board_info addon_spi_board_info_con1[] __initdata = {
        {
                .modalias = "mcp3202",
                .max_speed_hz = 1000000,
                .bus_num = 1,
                .chip_select = 0,
        },
};
 
static struct spi_board_info addon_spi_board_info_con2[] __initdata = {
        {
                .modalias = "mcp3202",
                .max_speed_hz = 1000000,
                .bus_num = 2,
                .chip_select = 0,
        },
};
 
static struct regulator_consumer_supply fixed5v0_consumers_con1[] = {
        REGULATOR_SUPPLY("vref", "spi1.0"),
};
 
static struct regulator_consumer_supply fixed5v0_consumers_con2[] = {
        REGULATOR_SUPPLY("vref", "spi2.0"),
};

これを見ると、CON1がspi1.0でCON2がspi2.0なようです。

以下は余談です。

このソース見ていて、ゴミを発見。

static struct {
        iomux_v3_cfg_t *pads;
   (途中省略)
        struct addon_gpio do2;
} addon_data[NR_ADDON_INTERFACES] = {
        [ADDON_INTERFACE1] = {
   (途中省略)
        },
        [ADDON_INTERFACE2] = {
                .pads           = addon_pinctrl_pads_con2,
   (途中省略)
                .supply_name    = "mcp3202 Vref CON2",
                .adum1401_ve1   = ADDON_GPIO(IMX_GPIO_NR(1, 20),    <===★
                                             "ADUM1401_VE1_CON1"),
                .di1            = ADDON_GPIO(IMX_GPIO_NR(2, 16),
                                             "DI1_CON1"),
                .di2            = ADDON_GPIO(IMX_GPIO_NR(2, 17),
                                             "DI2_CON1"),
                .do1            = ADDON_GPIO(IMX_GPIO_NR(1, 0),
                                             "DO1_CON1"),
                .do2            = ADDON_GPIO(IMX_GPIO_NR(1, 1),
                                             "DO2_CON1"),
                .adum1401_ve1   = ADDON_GPIO(IMX_GPIO_NR(3, 3),
                                             "ADUM1401_VE1_CON2"),
                .di1            = ADDON_GPIO(IMX_GPIO_NR(2, 30),
                                             "DI1_CON2"),
                .di2            = ADDON_GPIO(IMX_GPIO_NR(2, 31),
                                             "DI2_CON2"),
                .do1            = ADDON_GPIO(IMX_GPIO_NR(1, 2),
                                             "DO1_CON2"),
                .do2            = ADDON_GPIO(IMX_GPIO_NR(1, 3),
                                             "DO2_CON2"),
        },
};

この★の行から最初の".do2"までは、コピペミスかな、と思います。

--
なかむら

中村です。

コピペミスの訂正と、書き忘れです。

> /dev/iio:deviceN と evices/iio:deviceN の下を探してみましたが、
> それらしき情報はなさそうです。(探したりない?)

上の"evices/iio:deviceN"は、
" /sys/bus/iio/devices/iio:deviceN"の間違いです。

"/dev/iio:deviceN"は、「その下」ということではなくて、
IOCTLで何かとれないかな?ということを調べてみました。

iioのioctlの実装は drivers/iio/industrialio-core.c にありますが、

static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
        struct iio_dev *indio_dev = filp->private_data;
        int __user *ip = (int __user *)arg;
        int fd;
 
        if (!indio_dev->info)
                return -ENODEV;
 
        if (cmd == IIO_GET_EVENT_FD_IOCTL) {
                fd = iio_event_getfd(indio_dev);
                if (copy_to_user(ip, &fd, sizeof(fd)))
                        return -EFAULT;
                return 0;
        }
        return -EINVAL;
}

となっていて、IIO_GET_EVENT_FD_IOCTL以外は何もないようです。

--
なかむら

なかむらさま

森です。
レスありがとうございました。
どのあたりを、どう確認して良いのか分かりませんでしたので、
大変助かりました。