2017-09-18 15 views
1

tmp102温度センサー用のカーネルドライバを作成したいとします。 1つのプロジェクトでは、他の2つのセンサーに1つのセンサーしかありません。カーネルモジュールが固定数ではなくN個のセンサーをサポートできるようにしたい。私は1つ以上のstruct i2c_clientを管理し、それぞれのsysfsエントリを作成することに問題があります。ここで私はそれをやっている方法は次のとおりです。1つのドライバモジュールで複数のi2c_clientsを処理する(sysfsを使用)

  1. 私は私がI2C_BOARD_INFO()を提供するデバイスごとにstruct i2c_client*を取得probe()機能で。

  2. 次に、モジュールのメインディレクトリをsysfsにするために、kobject_create_and_add("tmp102", kernel_kobj)を取得します。静的属性を作成するためのポインタを取得し、私はsysfs_create_group()を作成していた各デバイスに対して

  3. 。属性は、(*show)()(*store)()ポインタが静的関数に設定されています。私はI2C経由で読みたい本機能で

    static ssize_t tmp102_sysfs_thigh_get_one(struct kobject *kobj, struct kobj_attribute *attr, char *buf) 
    

。問題は、私は何とかこののsysfsエントリにリンクされなければならないデバイスのためのstruct i2c_client *を取得する方法がわからない、とI2Cアドレスがある...です!

i2c_clientをsysfsのエントリに正しくリンクすると、関数内にI2Cアドレスを取得できますか?

理想的には、私は機能のほんの一組(属性ごとに1つ)を持っていると思います。 のsysfsツリーはそのようになります。

/sysfs/kernel/tmp102 
    | 
    |-> <hex i2c address, e.g. /48> 
    | | 
    | |-> temperature 
    | 
    | 
    |-> /49 
     | 
     |-> temperature 

私は両方の「温度」は、それが書くべき先のI2Cアドレスを、決定することができる同じ機能を、使用する属性たいです。

多分私のアーキテクチャは間違っていますか?その場合、複数のi2c_clientを処理する必要があるドライバの場合はどうすればよいでしょうか?

EDIT:

私はstruct device_attributeの代わりに、定期的なattribute Sを使用することにしました。私の理解では、struct i2c_clientと同じ、通常の属性を使用するときにstruct deviceポインタを取得することは容易ではありません。それらは簡単にkobject/sys/kernelからリンクされていません。私はこのプロジェクトで自分の属性を持つ必要があります。 device_attribute sが/sys/devicesで見つけることができます - 私はsysfs_create_groupを使用して、私のデバイスのkobjectdevice_attributeグループとをリンクさ。 sysfs_create_linkを使用し、デバイスのkobject/sys/kernel/tmp102にリンクしました。このようにして、各デバイスのフォルダ(リンク)を作成して、元の属性フォルダ(/sys/devices)をポイントすることができます。

+0

ドライバ内のボード情報を作成して埋め込むことは、Linuxカーネルで使用されるモデルとは異なります。あなたは、(アドレスへの)無関係なドライバを作成し、ACPI、デバイスツリー、またはレガシープラットフォームのデータとなるボード情報の別のソースを提供する必要があります。 – 0andriy

+0

I2C_BOARD_INFOがドライバにないことがわかりません。これは、ビルドプロセスの前にカーネルに適用されるパッチ内にあります。このカーネルはまだデバイスツリーをサポートしていません。モジュール自体はアドレスに依存しません。私はここに何かを逃していますか – Bart

+0

あなたの投稿を誤読したようです。 – 0andriy

答えて

2

まず、あなたはすでにのsysfsインターフェースを持つTMP102ためのカーネルドライバがあることを知っている必要があります。 drivers/hwmon/tmp102.cをご覧ください。

今、あなたの問題のために、あなたはあなたのsysfsコールバックに渡されstruct kobjectを持っています。kobj_to_dev()に電話して、デバイスへのポインタを取得できます。次に、たとえば、dev_get_drvdata()を使用して、i2cクライアントへのポインタを含む独自のプライベート構造へのポインタを取得できます。プローブにdev_set_drvdata()と設定することを忘れないでください。

例はdrivers/rtc/rtc-ds1343.cですが、spi_driverを使用しています。

+0

問題は 'kobj_to_dev()'を使うことができないことです。なぜなら、メインのkobjの親は 'kernel_kobj'ですからです。フォルダを '/ sys/kernel/tmp102'に置いて欲しいです。今ではすべてのデバイスが独自のフォルダを作成し、アドレスが '0x48'のクライアントに対してはフォルダは' 48'になります。このkobjの親は 'tmp102' kobjになります。だから私のsysfs '(* show)()'関数に渡されるこの 'struct kobject'は、デバイスkobjでコアされていません。 '/ sys/kernel/tmp102 /'からデバイスkobjにアクセスできるように 'struct kobjects'を整理する方法はわかりません – Bart

+0

第2の考えでは、おそらくプレーンではなく' device_attribute'を使うべきでしょう属性グループを 'kernel_kobj'に接続しますか?私はデバイスポインタにアクセスし、 'dev_get_drvdata()'か 'to_i2c_client()'のどちらかを使いますか?私はボードを取り戻すと、このアプローチをチェックします。 – Bart

関連する問題