Linux または Android でファイル システムを追加する属性インターフェイスを解析する方法

Linux または Android でファイル システムを追加する属性インターフェイスを解析する方法

最初のもの:

1. 主要なヘッダーファイルを追加します。

#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kobject.h>

2. 既存のドライバー ファイルで「DEVICE_ATTR」キーワードを検索します。存在する場合は、次のように既存の方法を参照して追加します。

unsigned int Gpio134_OtgID = 134; //グローバル変数を定義する static unsigned int otgid_status = 1;
…

3. ファイルシステムの読み取りおよび書き込み機能を定義します。

//ホストまたはデバイス モード用の zhaojr gpio134 制御 OTG ID を追加します。 
静的 ssize_t setotgid_store(構造体デバイス *dev、構造体デバイス属性 *attr、const char *buf、size_t カウント)       
{
 符号なし整数 ret=0;
 pr_err("%s:\n", __func__); 
 // ret = kstrtoint(buf, 10, &otgid_status);
 ret = kstrtouint(buf, 10, &otgid_status);
 //sscanf(buf, "%lu", &otgid_status);
 (戻り値<0)の場合{
  pr_err("%s::kstrtouint() が失敗しました \n", __func__);
 }
 //sscanf(buf, "%d", &otgid_status);
 pr_err("%s: otgid_status=%d \n", __func__,otgid_status); 
 (otgid_status > 0)の場合{
  gpio_set_value(Gpio134_OtgID、1); 
 }それ以外{
  gpio_set_value(Gpio134_OtgID、0); 
 }
 カウントを返します。
}
静的 ssize_t setotgid_show(構造体デバイス *dev、構造体デバイス属性 *attr、char *buf)  
{
 pr_err("%s:\n", __func__); 
 sprintf(buf, "%d\n",otgid_status) を返します。
}
//静的DEVICE_ATTR_RW(setotgid);
/*構造体デバイス属性 dev_attr_setotgid = {     
  .attr = {.name ="setotgid",       
  .mode = 0664},   
  .show = setotgid_show、       
  .store = setotgid_store、    
};*/ 
//setotgid の一貫性、最初のパラメーター setotgid は setotgid_show および setotgid_store と一致している必要があります static DEVICE_ATTR(setotgid, 0664, setotgid_show, setotgid_store); 
//zhaojr の追加終了
静的構造体device_attribute *android_usb_attributes[] = {
 &dev_attr_state、
 &dev_attr_setotgid, //setotgid と DEVICE_ATTR で定義された名前は NULL で一致している必要があります
};

4. プローブ()関数で特定のGPIOピンの要求と初期化を定義する

静的 int mdss_mdp_probe(構造体プラットフォームデバイス *pdev)
{
................................................................................................................
//zhaojr gpio134 を USB ホストまたはデバイス モードに追加します
 ret_status = gpio_request(Gpio134_OtgID、"Gpio134-OtgID");
 ret_status<0の場合{
  pr_err("usb ガジェット configfs %s::Gpio134_OtgID gpio_request が失敗しました\n",__func__); 
  }
 pr_err("android_device_create()::Gpio134_OtgID gpio_request OK\n"); 
 gpio_direction_output(Gpio134_OtgID、1);
 if(otgid_status > 0){ //カスタム初期化ステータスがある場合は、この判断を追加します。ない場合は、if else 操作を追加する必要はありません。pr_err("%s-Gpio134_OtgID pin set 1\n", __func__);
  gpio_set_value(Gpio134_OtgID、1); 
  //スリープ(5);
 }それ以外{
  pr_err("%s-Gpio134_OtgIDピンが0に設定されました\n", __func__);
  gpio_set_value(Gpio134_OtgID、0); 
  //スリープ(5);
 }
 //zhaojr の追加終了
.............................................................
}

5. remove() 関数にリソース解放を追加する

静的 int mdss_mdp_remove(構造体プラットフォームデバイス *pdev)
{
 構造体 mdss_data_type *mdata = platform_get_drvdata(pdev);
 (!mdata) の場合
  -ENODEV を返します。 
 pr_err("%s\n", __func__);
 gpio_free(Gpio134_OtgID); //zhaojr は空き gpio otgid ピンを追加します
 .............................................................
}

2番目の方法:

オーディオアンプのオン/オフを切り替えるための制御インターフェースを追加するなど、追加するドライバーファイルで「DEVICE_ATTR」キーワードが検索されない場合:
1. 主要なヘッダーファイルを追加します。

#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kobject.h>

2. グローバル変数を定義し、オープン インターフェイスとクローズ インターフェイスを定義し、属性配列を整理します。

// クローズまたはスピーカー PA を有効にするために zhaojr gpio63 を追加します
構造体kobject *spk_pa_kobj = NULL;
unsigned int gpio63_spk_pa_gpio; //スピーカーpa icの有効化
//外部符号なしint gpio63_spk_pa_gpio;
静的符号なし整数 SpkPa_Gpio_Enable = 0;
静的 ssize_t spkpaon_store(構造体デバイス *dev、構造体デバイス属性 *attr、const char *buf、size_t カウント)  
{
 符号なし整数 ret=0;
 // ret = kstrtoint(buf, 10, &backlight_enable);
 ret = kstrtouint(buf, 10, &SpkPa_Gpio_Enable);
 (戻り値<0)の場合{
 pr_err("%s::kstrtouint() が失敗しました \n", __func__);
 }
 pr_err("%s: SpkPa_Gpio_Enable=%d \n", __func__,SpkPa_Gpio_Enable); 
 SpkPa_Gpio_Enable > 0の場合{
 //gpio_set_value(gpio63_spk_pa_gpio, 1); 
 pr_err("%s: gpio_set_value gpio63 スピーカー pa 有効化 \n", __func__);
 //パワーアンプのオープンタイミング gpio_set_value(gpio63_spk_pa_gpio,0);
 ウデレイ(8);
 gpio_set_value(gpio63_spk_pa_gpio,1);
 ウデレイ(8);
 gpio_set_value(gpio63_spk_pa_gpio,0);
 ウデレイ(8);
 gpio_set_value(gpio63_spk_pa_gpio,1);
 //sdm660_cdc->ext_spk_pa_set = true;
 }それ以外{
 pr_err("%s: gpio_set_value gpio63 スピーカー pa 無効 \n", __func__);
 //パワーアンプのシャットダウンタイミング gpio_set_value(gpio63_spk_pa_gpio,0);
 遅延(600);
 //sdm660_cdc->ext_spk_pa_set = false; 
 }
 カウントを返します。
}
静的 ssize_t spkpaon_show(構造体デバイス *dev、構造体デバイス属性 *attr、char *buf) 
{ 
 sprintf(buf, "%d\n",SpkPa_Gpio_Enable) を返します。
} 
静的 DEVICE_ATTR(spkpaon、0664、spkpaon_show、spkpaon_store);
静的構造体属性 *spkpa_attributes[] = {
 &dev_attr_spkpaon.attr、
 NULL
};
静的定数構造体 attribute_group apkpa_attr_group = {
 .attrs = spkpa_attributes、
 NULL
};
//zhaojr の追加終了

3.probe() 関数にファイル システム属性インターフェイスの登録を追加します。
パワーアンプは登録時に初期化する必要がないため、sdm660_cdc->spk_pa_gpio(GPIO63)ではprobe()関数は動作せず、リクエストのみが動作します。具体的なリクエスト操作については、msm8953のオーディオ部のEARとスピーカー出力のサウンド設定のオーディオ部を参照してください。

vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/msm-analog-cdc.c ファイル操作

静的 int msm_anlg_cdc_probe(構造体プラットフォームデバイス *pdev)
{
 戻り値:
 構造体 sdm660_cdc_priv *sdm660_cdc = NULL;
 構造体 sdm660_cdc_pdata *pdata;
 整数adsp_state;
 ...............................
 dev_set_drvdata(&pdev->dev, sdm660_cdc);
 //カンティン追加
 sdm660_cdc->spk_pa_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,speaker-pa", 0);
 gpio_is_valid(sdm660_cdc->spk_pa_gpio) の場合
 pr_err("%s、sdm660_cdc->spk_pa_gpio が指定されていません\n",__func__);
 それ以外{
 pr_err("%s、sdm660_cdc->spk_pa_gpio は %d です\n",__func__,sdm660_cdc->spk_pa_gpio);
 ret = gpio_request(sdm660_cdc->spk_pa_gpio、"spk_pa");
 (戻り){
 pr_err("spk_pa_gpio 要求が失敗しました。ret=%d\n",ret);
 gpio_free(sdm660_cdc->spk_pa_gpio);
 }
 }
 //カンティン終了
 ret = snd_soc_register_codec(&pdev->dev,
   &soc_codec_dev_sdm660_cdc,
   msm_anlg_cdc_i2s_dai、
   配列サイズ(msm_anlg_cdc_i2s_dai));
 (戻り){
 dev_err(&pdev->dev,
 "%s:snd_soc_register_codec はエラー %d で失敗しました\n",
 __func__, 戻り値);
 err_supplies に移動します。
 }
 BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier);
 BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc);
 //zhaojr による追加
 gpio63_spk_pa_gpio = sdm660_cdc->spk_pa_gpio; //デバイスツリーで定義されたIOポート番号を取得しますpk_pa_kobj = kobject_create_and_add("spk_pa", NULL); ///sys/spk_pa/directoryを作成しますret = sysfs_create_group(spk_pa_kobj, &apkpa_attr_group); ///sys/class/spk_pa/spkpaonを作成しますif (ret)
 dev_err(&pdev->dev,"%s:sysfs_create_group がエラーで失敗しました\n",__func__);
 //zhaojr の追加終了 
 ...............................

4. 削除関数でリソースを解放する

静的 int msm_anlg_cdc_remove(構造体プラットフォームデバイス *pdev)
{
 構造体 sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev);
 構造体 sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data;
 整数カウント;
 //zhaojr によって追加 //リソースを解放 gpio_free(sdm660_cdc->spk_pa_gpio);
 kobject_put(spk_pa_kobj); //キー関数sysfs_remove_group(spk_pa_kobj, &apkpa_attr_group); //キー関数//end zhaojr add
 (count = 0; count < sdm660_cdc->child_count &&
 カウント < ANLG_CDC_CHILD_DEVICES_MAX; カウント++)
 プラットフォームデバイスの登録解除(
 sdm660_cdc->pdev_child_devices[数]);
 snd_soc_unregister_codec(&pdev->dev);
 msm_anlg_cdc_disable_supplies(sdm660_cdc、pdata);
 wcd9xxx_spmi_irq_exit();
 devm_kfree(&pdev->dev, sdm660_cdc);
 0を返します。
}

要約する

Linux または Android でファイルシステム属性インターフェイスを追加する方法についての解析に関するこの記事はこれで終わりです。Linux ファイルシステムの属性インターフェイスに関連するその他のコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • PythonはLinuxのファイル(フォルダ)の権限を変更します
  • Linux シェル - 識別によってファイル システム属性をテストする方法の例
  • Linux の crw、brw、lrw などのファイル属性は何ですか?
  • Linux でファイル属性を表示する詳細な例 (ls、lsattr、file、stat)
  • Linux rwxrwxrwt フォルダ属性についての簡単な説明
  • Linuxファイルの基本属性の知識ポイントのまとめ

<<:  VueでTypeScriptを使用する方法

>>:  CentOS 6.2 に MySQL 5.7.28 をインストールするチュートリアル (mysql ノート)

推薦する

vue+echartsチャートの使用に関する問題記録

序文echarts は私が最もよく使用するチャート作成ツールであり、非常に完全なエコシステムとコンテ...

Docker環境を構築する簡単な方法

まず、Docker とは何かを理解しましょう。 Docker は、アプリケーションをデプロイするため...

JavaScript プロトタイプのデータ共有とメソッド共有の実装を調べる

データ共有プロトタイプにはどのようなデータを書き込む必要がありますか?共有する必要があるデータはプロ...

Vue+el-tableはセルの結合を実現します

この記事の例では、参考までにセルの結合を実現するためのel-tableの具体的なコードを共有していま...

Nginx プロキシを使用してフロントエンドのクロスドメイン問題を解決する方法

序文Nginx (「エンジン エックス」と発音) は、リバース プロキシ、ロード バランサ、HTTP...

nginx パニック問題の解決方法の詳細な説明

nginx パニック問題に関しては、まず nginx の起動プロセス中に、マスター プロセスが構成フ...

ARGB、RGB、RGBAの違いと紹介

ARGB は、アルファ (透明度) チャネルが追加された RGB カラー モードであり、32 ビット...

nginx ip ブラックリストの動的禁止の例

ウェブサイトが悪意を持ってリクエストされた場合、IP アドレスをブラックリストに登録することは重要な...

ボタンを使用してフォームを送信する代わりに、画像を使用してフォームを送信します。

コードをコピーコードは次のとおりです。 <フォームメソッド="post" ...

JSはclip-pathを使用して動的領域クリッピング機能を実装します

背景今日、CodePen を閲覧していたところ、非常に興味深い効果を見つけました。 CodePen ...

vue+openlayer をベースにマップの集約と散乱効果を実現

目次序文:結果: 1.重合効果: 2. 散布効果:具体的な実装手順: 1. プロジェクトにOpenL...

要素テーブルの行と列のドラッグを実装する例

要素 ui テーブルにはドラッグ アンド ドロップによる並べ替え機能が組み込まれておらず、サードパー...

HTML の大なり、小なり、スペース、引用符などでよく使用されるエスケープ コードのリスト。

表は以下のとおりです。 HTMLソースコード結果を表示説明する&lt; <未満記号また...

Ubuntuがネットワークに接続できない場合の解決策

仮想マシン内の Ubuntu がネットワークに接続できない場合の効果的な解決策: 1. Ubuntu...

MySQL マスタースレーブ同期における server-id の例の詳細な説明

序文MySQL クラスターを構築する場合、当然のことながら、データの一貫性を確保するために、データベ...