alanhc
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: i2c driver url: https://hackmd.io/NlfiWjacQiCMbqh4UU_Dcg lastSync: 2025-07-05T10:41:39.776Z --- ## pmbus 最主要是 `module_i2c_driver(mpc42013_driver);` ,其 `struct` 定義: - `static struct i2c_driver mpc42013_driver` - `.driver` - `.probe_new` - .`remove` - `.id_table` | 欄位名稱 | 類型 | 作用 | 什麼時候會被呼叫 | | ------------ | ------------------------------------- | ---------------------------------------------- | ------------------------------------- | | `.driver` | `struct device_driver` | 提供「驅動的基本資訊」與「配對資訊」,像是名字、支援哪些 Device Tree 相容字串等 | 核心 driver model 用來做比對與註冊 | | `.probe_new` | `int (*)(struct i2c_client *client)` | 驅動成功匹配裝置時會執行的初始化函式(新 API,建議使用) | 有相容裝置註冊時由 `i2c_device_probe()` 呼叫 | | `.remove` | `void (*)(struct i2c_client *client)` | 當裝置被移除時(例如 hotplug 拔除、模組卸載),這個函式會負責做清理 | 在驅動卸載、裝置移除時由 `i2c_device_remove()` 呼叫 | | `.id_table` | `const struct i2c_device_id *` | 用於 legacy 比對(非 Device Tree 的平台),像 x86 上的硬體 | 傳統平台配對用,會傳入 `probe()` 的第二參數 | 這是來自 [`include/linux/i2c.h` ](https://elixir.bootlin.com/linux/v6.15.4/source/include/linux/i2c.h#L974) 的 marco ### `module_i2c_driver` - module_i2c_driver marc ``` #define module_i2c_driver(__i2c_driver) \ module_driver(__i2c_driver, i2c_add_driver, i2c_del_driver) ``` - 再展開在`include/linux/device.h`的 `module_driver` ``` #define module_driver(__driver, __register, __unregister) \ static int __init __driver##_init(void) \ { return __register(&(__driver)); } \ static void __exit __driver##_exit(void) \ { __unregister(&(__driver)); } \ module_init(__driver##_init); \ module_exit(__driver##_exit); ``` 裡面的要填寫的結構定義在 `include/linux/i2c.h` ``` struct i2c_driver { unsigned int class; // 當 kernel 找到匹配的 I2C 裝置後會呼叫 probe() int (*probe)(struct i2c_client *client); // 裝置移除時呼叫 void (*remove)(struct i2c_client *client); // 系統關機或重新啟動時會呼叫 void (*shutdown)(struct i2c_client *client); // SMBus alert 機制(可選) void (*alert)(struct i2c_client *client, enum i2c_alert_protocol protocol, unsigned int data); // 可選:如 ioctl 介面給使用者空間 int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); // 核心的 generic driver model 結構 struct device_driver driver; // 用來匹配 I2C 裝置 ID(legacy) const struct i2c_device_id *id_table; // 若是 Device Tree 平台,這是用來 match 的 DT compatible list const struct of_device_id *of_match_table; // 用於非 OF 平台上的 auto-detect(常用於 hwmon) int (*detect)(struct i2c_client *client, struct i2c_board_info *info); const unsigned short *address_list; // 核心維護的 device list struct list_head clients; u32 flags; // enum i2c_driver_flags 中的位元旗標 }; ``` 其中 `.driver` 是在 `include/linux/device.h` 的`struct device_driver` - `include/linux/device.h` ``` /** * struct device_driver - The basic device driver structure * @name: Name of the device driver. * @bus: The bus which the device of this driver belongs to. * @probe: Callback to check if the driver can handle a given device. * @remove: Callback to remove the device. * ... */ struct device_driver { const char *name; struct bus_type *bus; struct module *owner; const struct of_device_id *of_match_table; const struct acpi_device_id *acpi_match_table; int (*probe) (struct device *dev); void (*remove) (struct device *dev); void (*shutdown) (struct device *dev); int (*suspend) (struct device *dev, pm_message_t state); int (*resume) (struct device *dev); ... }; ``` | 欄位 | 說明 | | ------------------ | --------------------------------------------------- | | `name` | 驅動名稱,用於 sysfs (`/sys/bus/.../drivers/`) | | `bus` | 所屬的 bus(如 `i2c_bus_type`, `pci_bus_type`) | | `owner` | 通常填入 `THIS_MODULE`,讓 kernel 知道這個 driver 的 module 是誰 | | `probe()` | 當有裝置與此驅動匹配時,會被呼叫 | | `remove()` | 裝置移除時呼叫 | | `of_match_table` | Device Tree 的 `compatible` 比對表 | | `acpi_match_table` | ACPI 裝置比對表(在 x86 平台常用) | ### `.driver` - name - of_match_table: - `.compatible` : 會去找對應在 Device Tree 中的 compatible 欄位 - `.data` (optional) ### `.probe` - 定義在 `include/linux/i2c.h` 裡的 `struct i2c_driver` 中: ``` struct i2c_driver { ... int (*probe)(struct i2c_client *client, const struct i2c_device_id *id); ... }; ``` - 會在 [`drivers/i2c/i2c-core-base.c`](https://elixir.bootlin.com/linux/v6.15.4/source/drivers/i2c/i2c-core-base.c#L491) 裡面的 `i2c_device_probe()` 被呼叫,這是當有驅動與裝置配對成功時 ``` // drivers/i2c/i2c-core-base.c // 函式名稱:i2c_device_probe() static int i2c_device_probe(struct device *dev) { ... const struct i2c_device_id *id; // 把 driver 轉成 i2c_driver 型別 struct i2c_driver *driver = to_i2c_driver(dev->driver); ... if (driver->probe_new) { // 如果你實作的是 probe_new,就用這個 status = driver->probe_new(client); } else { // 否則使用傳統的 probe(),這時還會找 id_table id = i2c_match_id(driver->id_table, client); if (!id) return -ENODEV; status = driver->probe(client, id); } ... } ``` ```mermaid graph TD subgraph 系統事件 A1[Device Tree/ACPI 宣告一個 I2C device] A2["或是手動呼叫 i2c_new_client_device()"] end subgraph I2C Core B1[i2c-core 建立 struct device] B2[呼叫 bus_type.match: i2c_device_match] B3[match 成功 → 呼叫 bus_type.probe: i2c_device_probe] B4["進入驅動的 probe() or probe_new()"] end A1 --> B1 A2 --> B1 B1 --> B2 B2 -->|match| B3 --> B4 ``` ```mermaid graph TD A[Device Tree / Platform 裝置註冊] --> B[i2c-core-base.c] B --> C["i2c_device_probe()"] C -->|driver->probe_new 存在?| D["是 → 呼叫 probe_new()"] C -->|否 → 找 id_table 比對| E["呼叫 probe(client, id)"] ``` | 名稱 | 傳統 API | 新 API(建議用) | | ------------- | ------------- | ---------- | | `probe()` | 帶 `id_table` | 否 | | `probe_new()` | 不帶 `id_table` | ✅ 較簡單現代寫法 | |差異|`probe()`|`probe_new()`| |---|---|---| |參數|`struct i2c_client *, const struct i2c_device_id *`|`struct i2c_client *`| |匹配來源|傳統 I2C core 用 `.id_table` 傳入|Device Tree / ACPI 直接用 `.of_match_table`| |適用平台|非 OF、非 ACPI 系統|現代嵌入式系統(使用 Device Tree 或 ACPI)| |哪個比較新?|✅ 比較舊|✅ 建議使用的新式方式| ### `.id_table` legacy 平台(非 Device Tree)配對用 - 用於非 Device Tree 的平台(例如 x86 BIOS 平台) - 比對方式是透過 `client->name` 比對 `mychip` 字串 - 用 `probe_new` 的時候不一定要寫 ## debug - `dev_info(&client->dev, "Using probe_new() for device %s\n", dev_name(&client->dev));` ## TODO - https://www.kernel.org/doc/html/v6.12/driver-api/i2c.html - https://jasonblog.github.io/note/linux_kernel/Modern_Maker/Day11.html - [今晚我想來點不一樣的 Driver: I2C Device](https://hackmd.io/@RinHizakura/BJDTZnUsF)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully