並行埠裝置

parport_register_driver

parport_register_driver (driver)

註冊並行埠裝置驅動程式

引數

driver

描述驅動程式的結構

並行埠裝置驅動程式可以呼叫此函式,以便接收有關係統中找到的埠以及不再可用的埠的通知。

driver 結構由呼叫者分配,並且在呼叫 parport_unregister_driver() 之後才能解除分配。

如果使用非裝置模型:驅動程式的 attach() 函式可能會阻塞。attach() 函式獲得的埠在回撥期間有效,但如果驅動程式想要複製指標,則必須呼叫 parport_get_port()。對該埠呼叫 parport_register_device() 將為您執行此操作。

驅動程式的 detach() 函式可能會阻塞。detach() 函式獲得的埠在回撥期間有效,但如果驅動程式想要複製指標,則必須呼叫 parport_get_port()

成功時返回 0。非裝置模型將始終成功。但新裝置模型可能會失敗,並將返回錯誤程式碼。

module_parport_driver

module_parport_driver (__parport_driver)

用於註冊模組化 parport 驅動程式的輔助宏

引數

__parport_driver

要使用的 struct parport_driver

說明

用於 parport 驅動程式的輔助宏,這些驅動程式在模組初始化和退出時不做任何特殊處理。這消除了大量樣板程式碼。每個模組只能使用此宏一次,並且呼叫它會替換 module_init()module_exit()

int parport_yield(struct pardevice *dev)

暫時放棄並行埠

引數

struct pardevice *dev

並行埠上的裝置

說明

如果這樣做對其他驅動程式有幫助,則此函式會放棄埠。之後,它嘗試使用 parport_claim() 重新宣告埠,並且返回值與 parport_claim() 的返回值相同。如果失敗,則埠保持未宣告狀態,並且驅動程式有責任重新宣告埠。

parport_yield()parport_yield_blocking() 函式用於標記驅動程式中的點,其他驅動程式可以在這些點宣告埠並使用其裝置。放棄埠類似於釋放埠並重新宣告埠,但效率更高,因為如果沒有其他裝置需要該埠,則不會採取任何操作。事實上,即使有其他裝置在等待,但當前裝置仍在“時間片”內,也不會執行任何操作。預設時間片為半秒,但可以透過 /proc 介面進行調整。

int parport_yield_blocking(struct pardevice *dev)

暫時放棄並行埠

引數

struct pardevice *dev

並行埠上的裝置

說明

如果這樣做對其他驅動程式有幫助,則此函式會放棄埠。之後,它嘗試使用 parport_claim_or_block() 重新宣告埠,並且返回值與 parport_claim_or_block() 的返回值相同。

int parport_wait_event(struct parport *port, signed long timeout)

等待並行埠上的事件

引數

struct parport *port

要等待的埠

signed long timeout

等待時間(以節拍為單位)

此函式最多等待 timeout 節拍,以等待並行埠上發生中斷。如果埠超時設定為零,則立即返回。

如果在超時時間段過去之前發生中斷,則此函式立即返回零。如果超時,則返回一。小於零的錯誤程式碼表示錯誤(很可能是掛起的訊號),呼叫程式碼應儘快完成正在執行的操作。

int parport_wait_peripheral(struct parport *port, unsigned char mask, unsigned char result)

等待狀態行在 35 毫秒內更改

引數

struct parport *port

要監視的埠

unsigned char mask

要監視的狀態行

unsigned char result

所選狀態行的所需值

此函式等待,直到遮蔽的狀態行具有所需的值,或直到經過 35 毫秒(請參閱 IEEE 1284-1994 第 24 至 25 頁,瞭解為什麼特別硬編碼此值)。maskresult 引數是位掩碼,位由 parport.h 中的常量定義:PARPORT_STATUS_BUSY,依此類推。

為了預測外圍裝置的快速響應,該埠開始時會快速輪詢。此快速輪詢時間是可配置的(使用 /proc),預設為 500 微秒。如果此埠的超時(請參閱 parport_set_timeout())為零,則快速輪詢時間為 35 毫秒,並且此函式不呼叫 schedule()。

如果此埠的超時為非零,則在快速輪詢失敗後,它會使用 parport_wait_event() 等待最多 10 毫秒,並在發生中斷時喚醒。

int parport_negotiate(struct parport *port, int mode)

協商 IEEE 1284 模式

引數

struct parport *port

要使用的埠

int mode

要協商到的模式

使用此函式協商到特定的 IEEE 1284 傳輸模式。mode 引數應為 parport.h 中以 IEEE1284_MODE_xxx 開頭的常量之一。

如果外圍裝置已接受協商到指定的模式,則返回值為 0;如果外圍裝置不符合 IEEE 1284 標準(或不存在),則返回值為 -1;如果外圍裝置已拒絕協商,則返回值為 1。

ssize_t parport_write(struct parport *port, const void *buffer, size_t len)

將資料塊寫入並行埠

引數

struct parport *port

要寫入的埠

const void *buffer

資料緩衝區(在核心空間中)

size_t len

要傳輸的資料位元組數

這將使用最近協商到的 IEEE 1284 傳輸模式(使用 parport_negotiate())將 buffer 的最多 len 個位元組寫入指定的埠,只要該模式支援正向傳輸(主機到外圍裝置)。

呼叫方有責任確保 buffer 的前 len 個位元組有效。

此函式返回傳輸的位元組數(如果為零或正數),否則返回錯誤程式碼。

ssize_t parport_read(struct parport *port, void *buffer, size_t len)

從並行埠讀取資料塊

引數

struct parport *port

要讀取的埠

void *buffer

資料緩衝區(在核心空間中)

size_t len

要傳輸的資料位元組數

這將使用最近協商到的 IEEE 1284 傳輸模式(使用 parport_negotiate())將最多 len 個位元組的 buffer 讀取到指定的埠,只要該模式支援反向傳輸(外圍裝置到主機)。

呼叫方有責任確保 buffer 的前 len 個位元組可用於寫入。

此函式返回傳輸的位元組數(如果為零或正數),否則返回錯誤程式碼。

long parport_set_timeout(struct pardevice *dev, long inactivity)

設定裝置的不活動超時

引數

struct pardevice *dev

埠上的裝置

long inactivity

不活動超時(以節拍為單位)

這將設定埠上特定裝置的不活動超時。這會影響諸如 parport_wait_peripheral() 之類的函式。特殊值 0 表示在處理此裝置時不呼叫 schedule()。

返回值是先前的不活動超時。

此裝置的 parport_wait_event() 的任何呼叫方都會被喚醒。

int __parport_register_driver(struct parport_driver *drv, struct module *owner, const char *mod_name)

註冊並行埠裝置驅動程式

引數

struct parport_driver *drv

描述驅動程式的結構

struct module *owner

drv 的所有者模組

const char *mod_name

模組名稱字串

並行埠裝置驅動程式可以呼叫此函式,以便接收有關係統中找到的埠以及不再可用的埠的通知。

如果 devmodel 為 true,則新裝置模型用於註冊。

drv 結構由呼叫者分配,並且在呼叫 parport_unregister_driver() 之後才能解除分配。

如果使用非裝置模型:驅動程式的 attach() 函式可能會阻塞。attach() 函式獲得的埠在回撥期間有效,但如果驅動程式想要複製指標,則必須呼叫 parport_get_port()。對該埠呼叫 parport_register_device() 將為您執行此操作。

驅動程式的 detach() 函式可能會阻塞。detach() 函式獲得的埠在回撥期間有效,但如果驅動程式想要複製指標,則必須呼叫 parport_get_port()

成功時返回 0。非裝置模型將始終成功。但新裝置模型可能會失敗,並將返回錯誤程式碼。

void parport_unregister_driver(struct parport_driver *drv)

登出並行埠裝置驅動程式

引數

struct parport_driver *drv

描述提供給 parport_register_driver() 的驅動程式的結構

當並行埠裝置驅動程式使用 parport_register_driver() 註冊自身時,即將解除安裝時,應呼叫此函式。

當它返回時,將不再呼叫驅動程式的 attach() 例程,並且對於呼叫 attach() 的每個埠,都將呼叫 detach() 例程。

保證在函式返回時,驅動程式的所有 attach() 和 detach() 呼叫都已完成。

struct parport *parport_get_port(struct parport *port)

增加埠的引用計數

引數

struct parport *port

這確保了 struct parport 指標保持有效,直到呼叫匹配的 parport_put_port()

void parport_put_port(struct parport *port)

減少埠的引用計數

引數

struct parport *port

對於每次呼叫 parport_get_port(),一旦不再需要該埠,就應呼叫此函式一次。當引用計數達到零(埠不再使用)時,將呼叫 free_port。

struct parport *parport_register_port(unsigned long base, int irq, int dma, struct parport_operations *ops)

註冊並行埠

引數

unsigned long base

基本 I/O 地址

int irq

IRQ 行

int dma

DMA 通道

struct parport_operations *ops

指向埠驅動程式的埠操作結構的指標

當並行埠(底層)驅動程式找到應提供給並行埠裝置驅動程式的埠時,它應呼叫 parport_register_port()baseirqdma 引數是為了方便埠驅動程式,對於沒有意義的埠,無需將其設定為任何特殊內容。可以透過調整返回並表示埠的 parport 結構的相關成員來更改它們。但是,在呼叫 parport_announce_port 之後,不應篡改它們。

如果系統中有已使用 parport_register_driver() 註冊自身的並行埠裝置驅動程式,則此時不會告知它們有關埠的資訊;這是由 parport_announce_port() 完成的。

ops 結構由呼叫者分配,並且在呼叫 parport_remove_port() 之前不得解除分配。

如果沒有記憶體來分配新的 parport 結構,則此函式將返回 NULL

void parport_announce_port(struct parport *port)

告知裝置驅動程式有關並行埠的資訊

引數

struct parport *port

要宣告的並行埠

在埠驅動程式使用 parport_register_port 註冊並行埠並執行任何必要的初始化或調整後,應呼叫 parport_announce_port(),以便通知已呼叫 parport_register_driver() 的所有裝置驅動程式。它們的 attach() 函式將被呼叫,並將 port 作為引數。

void parport_remove_port(struct parport *port)

登出並行埠

引數

struct parport *port

要登出的並行埠

當強制解除安裝並行埠驅動程式或並行埠變得無法訪問時,埠驅動程式必須呼叫此函式,以便處理仍想使用它的裝置驅動程式。

與該埠關聯的 parport 結構的其操作結構被替換為包含返回錯誤或只是不執行任何操作的“null”操作的結構。

已使用 parport_register_driver() 註冊自身的任何驅動程式都會收到通知,告知該埠不再可訪問,方法是使用 port 作為引數呼叫其 detach() 例程。

struct pardevice *parport_register_dev_model(struct parport *port, const char *name, const struct pardev_cb *par_dev_cb, int id)

在並行埠上註冊裝置

引數

struct parport *port

裝置連線到的埠

const char *name

用於引用裝置的名稱

const struct pardev_cb *par_dev_cb

包含回撥的結構

int id

要提供給裝置的裝置編號

此函式由並行埠裝置驅動程式呼叫,宣告裝置已連線到埠,並告知系統需要知道的所有資訊。

struct pardev_cb 包含指向回撥的指標。當此裝置驅動程式已宣告對埠的訪問許可權但另一個裝置驅動程式想要使用它時,會呼叫搶佔回撥函式 preempt。它會給出 private 作為其引數,並且如果它願意代表系統將埠釋放給另一個驅動程式,則應返回零。如果它想保持對埠的控制,則應返回非零,並且不會採取任何操作。驅動程式最好在搶佔回撥拒絕搶佔嘗試後儘快嘗試釋放埠。請注意,如果搶佔回撥樂於進行搶佔,則無需釋放埠;它是自動完成的。此函式可能不會阻塞,因為它可能從中斷上下文中呼叫。如果裝置驅動程式不支援搶佔,則 preempt 可以為 NULL

喚醒(“kick”)回撥函式 wakeup 在埠可用於宣告獨佔訪問許可權時呼叫;也就是說,保證可以從喚醒回撥函式內部呼叫 parport_claim()。如果驅動程式想要宣告埠,則應這樣做;否則,它無需採取任何操作。此函式可能不會阻塞,因為它可能從中斷上下文中呼叫。如果裝置驅動程式不希望被明確邀請以這種方式宣告埠,則 wakeup 可以為 NULL

中斷處理程式 irq_func 在並行埠收到中斷時呼叫。請注意,如果裝置驅動程式想要使用中斷,則應使用 parport_enable_irq(),並且還可以檢查表示埠的 parport 結構的 irq 成員。

並行埠(底層)驅動程式是已呼叫 request_irq() 並且首先呼叫其中斷處理程式的驅動程式。此處理程式執行硬體需要執行的任何操作來確認中斷(對於 PC 樣式埠,無需執行任何特殊操作)。然後,它會告知 IEEE 1284 程式碼有關中斷的資訊,這可能涉及根據當前的 IEEE 1284 階段對 IEEE 1284 事件做出反應。在此之後,它會呼叫 irq_func。不用說,irq_func 將從中斷上下文中呼叫,並且可能不會阻塞。

PARPORT_DEV_EXCL 標誌用於防止埠共享,因此僅應在與其他裝置驅動程式共享埠是不可能且會導致錯誤行為時使用。謹慎使用它!通常,flags 將為零。

此函式返回指向表示埠上裝置的結構的指標,或者如果記憶體不足以分配該結構的空間,則返回 NULL

void parport_unregister_device(struct pardevice *dev)

登出並行埠上的裝置

引數

struct pardevice *dev

指向表示裝置的結構的指標

這將撤消 parport_register_device() 的效果。

struct parport *parport_find_number(int number)

按編號查詢並行埠

引數

int number

並行埠號

這將返回具有指定編號的並行埠,如果沒有,則返回 NULL

已經完成了隱式的 parport_get_port();要丟棄對 parport_find_number() 提供的埠的引用,請使用 parport_put_port()

struct parport *parport_find_base(unsigned long base)

按基地址查詢並行埠

引數

unsigned long base

基本 I/O 地址

這將返回具有指定基地址的並行埠,如果沒有,則返回 NULL

已經完成了隱式的 parport_get_port();要丟棄對 parport_find_base() 提供的埠的引用,請使用 parport_put_port()

int parport_claim(struct pardevice *dev)

宣告對並行埠裝置的訪問許可權

引數

struct pardevice *dev

指向表示埠上裝置的結構的指標

此函式不會阻塞,因此可以從中斷上下文中使用。如果 parport_claim() 成功聲明瞭對埠的訪問許可權,則返回零,並且該埠可供使用。如果埠正在被另一個驅動程式使用,並且該驅動程式不願意放棄對埠的控制,則可能會失敗(返回非零)。

int parport_claim_or_block(struct pardevice *dev)

宣告對並行埠裝置的訪問許可權

引數

struct pardevice *dev

指向表示埠上裝置的結構的指標

此行為類似於 parport_claim(),但如果需要等待埠空閒,則會阻塞。返回值 1 表示它已休眠;0 表示它已成功,無需休眠。負錯誤程式碼表示失敗。

void parport_release(struct pardevice *dev)

放棄對並行埠裝置的訪問許可權

引數

struct pardevice *dev

指向表示並行埠裝置的結構的指標

此函式不會失敗,但不應在未宣告埠的情況下呼叫。同樣,如果埠已宣告,則不應嘗試再次宣告它。

struct pardevice *parport_open(int devnum, const char *name)

按規範裝置編號查詢裝置

引數

int devnum

規範裝置編號

const char *name

與裝置關聯的名稱

這個函式類似於 parport_register_device(),不同之處在於它透過裝置編號而不是連線到的埠來定位裝置。

除了 devnum 之外的所有引數都與 parport_register_device() 相同。返回值與 parport_register_device() 相同。

void parport_close(struct pardevice *dev)

關閉使用 parport_open() 開啟的裝置

引數

struct pardevice *dev

要關閉的裝置

這相當於 parport_open() 之於 parport_unregister_device() 之於 parport_register_device()。

16x50 UART 驅動

struct uart_8250_port *serial8250_get_port(int line)

檢索 struct uart_8250_port

引數

int line

序列埠線號

說明

此函式檢索特定線路的 struct uart_8250_port。此結構必須不能用於執行無法以其他方式訪問的 8250 或序列核心操作。它唯一的目的是使結構可用於執行時 PM 回撥,以進行上下文掛起/恢復。這裡做出的鎖定假設是沒有,因為如果對埠執行任何操作,則不應呼叫執行時 PM 掛起/恢復回撥。

void serial8250_suspend_port(int line)

掛起一個序列埠

引數

int line

序列埠線號

掛起一個序列埠。

void serial8250_resume_port(int line)

恢復一個序列埠

引數

int line

序列埠線號

恢復一個序列埠。

int serial8250_register_8250_port(const struct uart_8250_port *up)

註冊一個序列埠

引數

const struct uart_8250_port *up

序列埠模板

配置請求指定的序列埠。如果埠存在且正在使用,則首先結束通話並登出它。

然後探測該埠,並在必要時自動檢測 IRQ。如果此操作失敗,則返回一個錯誤。

成功後,該埠即可使用,並返回行號。

void serial8250_unregister_port(int line)

在執行時刪除一個 16x50 序列埠

引數

int line

序列埠線號

刪除一個序列埠。不得從中斷上下文中呼叫此方法。我們將埠交還給我們的控制。

有關相關 API,請參見 底層序列 API

脈衝寬度調製 (PWM)

脈衝寬度調製是一種主要用於控制提供給電氣裝置的功率的調製技術。

PWM 框架為 PWM 訊號的提供者和使用者提供了一個抽象。提供一個或多個 PWM 訊號的控制器被註冊為 struct pwm_chip。提供者應將此結構嵌入到驅動程式特定的結構中。此結構包含描述特定晶片的欄位。

一個晶片公開一個或多個 PWM 訊號源,每個訊號源都公開為 struct pwm_device。可以對 PWM 裝置執行操作,以控制訊號的週期、佔空比、極性和活動狀態。

請注意,PWM 裝置是獨佔資源:它們一次只能被一個使用者使用。

enum pwm_polarity

PWM 訊號的極性

常量

PWM_POLARITY_NORMAL

在佔空比期間為高電平訊號,在脈衝週期的剩餘時間內為低電平訊號

PWM_POLARITY_INVERSED

在佔空比期間為低電平訊號,在脈衝週期的剩餘時間內為高電平訊號

struct pwm_args

依賴於板的 PWM 引數

定義:

struct pwm_args {
    u64 period;
    enum pwm_polarity polarity;
};

成員

period

參考週期

polarity

參考極性

說明

此結構描述了附加到 PWM 裝置的依賴於板的引數。這些引數通常從 PWM 查詢表或裝置樹中檢索。

不要將此與 PWM 狀態混淆:PWM 引數表示使用者希望在此 PWM 裝置上使用的初始配置,而不是當前的 PWM 硬體狀態。

struct pwm_waveform

PWM 波形的描述

定義:

struct pwm_waveform {
    u64 period_length_ns;
    u64 duty_length_ns;
    u64 duty_offset_ns;
};

成員

period_length_ns

PWM 週期

duty_length_ns

PWM 佔空比

duty_offset_ns

上升沿相對於週期起點的偏移

說明

這是 PWM 波形的表示形式,是下面 struct pwm_state 的替代方案。它比 struct pwm_state 更具表現力,因為它包含 duty_offset_ns,因此可以表示零以外的偏移量(使用 .polarity = PWM_POLARITY_NORMAL)和 period - duty_cycle(.polarity = PWM_POLARITY_INVERSED)。

請注意,沒有明確的布林值用於啟用。 “停用”的 PWM 由 .period_length_ns = 0 表示。請進一步注意,“停用”的 PWM 的行為是未定義的。根據硬體的功能,它可能會驅動活動或非活動級別,變為高阻抗,甚至繼續切換。

所有三個成員的單位均為納秒。

struct pwm_device

PWM 通道物件

定義:

struct pwm_device {
    const char *label;
    unsigned long flags;
    unsigned int hwpwm;
    struct pwm_chip *chip;
    struct pwm_args args;
    struct pwm_state state;
    struct pwm_state last;
};

成員

label

PWM 裝置的名稱

flags

與 PWM 裝置關聯的標誌

hwpwm

PWM 裝置的每個晶片的相對索引

chip

提供此 PWM 裝置的 PWM 晶片

args

PWM 引數

state

上次應用的狀態

last

上次實現的狀態(用於 PWM_DEBUG)

void pwm_get_state(const struct pwm_device *pwm, struct pwm_state *state)

檢索當前 PWM 狀態

引數

const struct pwm_device *pwm

PWM 裝置

struct pwm_state *state

用於填充當前 PWM 狀態的狀態

說明

返回的 PWM 狀態表示先前呼叫 pwm_apply_might_sleep() 應用的狀態。驅動程式可能需要在將其程式設計到硬體之前稍微調整該狀態。如果從未呼叫 pwm_apply_might_sleep(),則此函式返回當前的硬體狀態(如果支援)或預設設定。

void pwm_init_state(const struct pwm_device *pwm, struct pwm_state *state)

準備一個新狀態,以便使用 pwm_apply_might_sleep() 應用

引數

const struct pwm_device *pwm

PWM 裝置

struct pwm_state *state

使用準備好的 PWM 狀態填充的狀態

說明

此函式準備一個狀態,該狀態稍後可以進行調整,並使用 pwm_apply_might_sleep() 應用到 PWM 裝置。這是一個方便的函式,它首先檢索當前的 PWM 狀態,然後使用 pwm->args 中定義的參考值替換週期和極性欄位。該函式返回後,您可以根據需要調整 ->enabled 和 ->duty_cycle 欄位,然後再呼叫 pwm_apply_might_sleep()

->duty_cycle 最初設定為零,以避免當前 ->duty_cycle 值超過 pwm_args->period 值的情況,如果使用者在不首先調整 ->duty_cycle 的情況下呼叫 pwm_apply_might_sleep(),這將觸發一個錯誤。

unsigned int pwm_get_relative_duty_cycle(const struct pwm_state *state, unsigned int scale)

獲取相對佔空比值

引數

const struct pwm_state *state

從中提取佔空比的 PWM 狀態

unsigned int scale

相對佔空比的目標比例

說明

此函式將儲存在 state 中的絕對佔空比(以納秒錶示)轉換為相對於週期的值。

例如,如果您想獲得以百分比表示的 duty_cycle,請呼叫

pwm_get_state(pwm, state); duty = pwm_get_relative_duty_cycle(state, 100);

返回

乘以 scale 的四捨五入的相對佔空比

int pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, unsigned int scale)

設定相對佔空比值

引數

struct pwm_state *state

要填充的 PWM 狀態

unsigned int duty_cycle

相對佔空比值

unsigned int scale

表示 duty_cycle 的比例

說明

此函式將相對佔空比轉換為絕對佔空比(以納秒錶示),並將結果放入 state->duty_cycle 中。

例如,如果您想配置 50% 的佔空比,請呼叫

pwm_init_state(pwm, state); pwm_set_relative_duty_cycle(state, 50, 100); pwm_apply_might_sleep(pwm, state);

返回

成功時返回 0,如果 duty_cycle 和/或 scale 不一致,則返回 -EINVALscale == 0 或 duty_cycle > scale

struct pwm_capture

PWM 捕獲資料

定義:

struct pwm_capture {
    unsigned int period;
    unsigned int duty_cycle;
};

成員

period

period

duty_cycle

PWM 訊號的佔空比(以納秒為單位)

struct pwm_ops

PWM 控制器操作

定義:

struct pwm_ops {
    int (*request)(struct pwm_chip *chip, struct pwm_device *pwm);
    void (*free)(struct pwm_chip *chip, struct pwm_device *pwm);
    int (*capture)(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_capture *result, unsigned long timeout);
    size_t sizeof_wfhw;
    int (*round_waveform_tohw)(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_waveform *wf, void *wfhw);
    int (*round_waveform_fromhw)(struct pwm_chip *chip, struct pwm_device *pwm, const void *wfhw, struct pwm_waveform *wf);
    int (*read_waveform)(struct pwm_chip *chip, struct pwm_device *pwm, void *wfhw);
    int (*write_waveform)(struct pwm_chip *chip, struct pwm_device *pwm, const void *wfhw);
    int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state);
    int (*get_state)(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state);
};

成員

request

用於請求 PWM 的可選鉤子

free

用於釋放 PWM 的可選鉤子

capture

捕獲和報告 PWM 訊號

sizeof_wfhw

驅動程式特定波形表示的大小(以位元組為單位)

round_waveform_tohw

struct pwm_waveform 轉換為驅動程式特定表示形式

round_waveform_fromhw

將驅動程式特定的波形表示形式轉換為 struct pwm_waveform

read_waveform

從硬體讀取驅動程式特定的波形表示形式

write_waveform

將驅動程式特定的波形表示形式寫入硬體

apply

原子地應用新的 PWM 配置

get_state

獲取當前 PWM 狀態。

struct pwm_chip

抽象 PWM 控制器

定義:

struct pwm_chip {
    struct device dev;
    const struct pwm_ops *ops;
    struct module *owner;
    unsigned int id;
    unsigned int npwm;
    struct pwm_device * (*of_xlate)(struct pwm_chip *chip, const struct of_phandle_args *args);
    bool atomic;
    bool uses_pwmchip_alloc;
    bool operational;
    union {
        struct mutex nonatomic_lock;
        spinlock_t atomic_lock;
    };
    struct pwm_device pwms[] ;
};

成員

dev

提供 PWM 的裝置

ops

此 PWM 控制器的回撥

owner

提供此晶片的模組

id

此 PWM 晶片的唯一編號

npwm

此晶片控制的 PWM 數量

of_xlate

給定裝置樹 PWM 說明符,請求 PWM 裝置

atomic

驅動程式的 ->apply() 是否可以在原子上下文中呼叫

uses_pwmchip_alloc

如果使用 pwmchip_allow 分配此晶片,則發出訊號

operational

如果晶片可以使用(或已登出),則發出訊號

{unnamed_union}

anonymous

nonatomic_lock

用於非原子晶片的互斥鎖

atomic_lock

用於原子晶片的互斥鎖

pwms

框架分配的 PWM 裝置陣列

bool pwmchip_supports_waveform(struct pwm_chip *chip)

檢查給定晶片是否支援波形回撥

引數

struct pwm_chip *chip

要測試的 pwm_chip

返回

當且僅當 PWM 晶片支援 pwm_set_waveform_might_sleep()pwm_round_waveform_might_sleep() 等波形函式時,才為 true

int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)

更改 PWM 裝置配置

引數

struct pwm_device *pwm

PWM 裝置

int duty_ns

“導通”時間(以納秒為單位)

int period_ns

一個週期的持續時間(以納秒為單位)

返回

成功時返回 0,失敗時返回負錯誤程式碼。

int pwm_enable(struct pwm_device *pwm)

啟動 PWM 輸出切換

引數

struct pwm_device *pwm

PWM 裝置

返回

成功時返回 0,失敗時返回負錯誤程式碼。

void pwm_disable(struct pwm_device *pwm)

停止 PWM 輸出切換

引數

struct pwm_device *pwm

PWM 裝置

bool pwm_might_sleep(struct pwm_device *pwm)

是否支援 pwm_apply_atomic()

引數

struct pwm_device *pwm

PWM 裝置

返回

如果可以從原子上下文中呼叫 pwm_apply_atomic(),則為 false。

int pwm_round_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf)

查詢硬體功能。不能在原子上下文中使用。

引數

struct pwm_device *pwm

PWM 裝置

struct pwm_waveform *wf

要舍入的波形和輸出引數

說明

通常,給定的波形無法由硬體精確實現,例如,因為硬體僅支援粗略的週期解析度或沒有 duty_offset。 如果現在將 wf 傳遞給 pwm_set_waveform_might_sleep(),此函式將返回實際實現的波形。

但是請注意,當您呼叫它時,世界不會停止旋轉,因此在執行

pwm_round_waveform_might_sleep(mypwm, &wf);
pwm_set_waveform_might_sleep(mypwm, &wf, true);

後者可能會失敗,例如,因為輸入時鐘在兩次呼叫之間改變了速率,並且無法再實現由 pwm_round_waveform_might_sleep() 確定的波形。

通常,wf 中傳遞的所有值都向下舍入到最接近的可能值(按 period_length_ns、duty_length_ns 然後是 duty_offset_ns 的順序)。 只有在不可能的情況下,值才會增長。 有關更正式的描述,請參見 pwm_set_waveform_might_sleep() 的文件。

返回

成功時返回 0,如果至少一個值必須向上舍入,則返回 1,否則返回負 errno。

上下文

可能睡眠。

int pwm_get_waveform_might_sleep(struct pwm_device *pwm, struct pwm_waveform *wf)

查詢有關當前配置的硬體。 不能在原子上下文中使用。

引數

struct pwm_device *pwm

PWM 裝置

struct pwm_waveform *wf

輸出引數

說明

wf 中儲存 PWM 的當前配置。 請注意,這等效於 pwm_get_state_hw()(而不是 pwm_get_state())用於 pwm_waveform。

返回

成功時返回 0 或負 errno

上下文

可能睡眠。

int pwm_set_waveform_might_sleep(struct pwm_device *pwm, const struct pwm_waveform *wf, bool exact)

應用新波形。 不能在原子上下文中使用。

引數

struct pwm_device *pwm

PWM 裝置

const struct pwm_waveform *wf

要應用的波形

bool exact

如果為 true,則不允許舍入

說明

通常,無法精確地實現請求的波形,例如,因為您請求 .period_length_ns = 100 ns,但是硬體只能設定 8.5 ns 的倍數的週期。 對於該硬體,傳遞 exact = true 會導致 pwm_set_waveform_might_sleep() 失敗並返回 -EDOM。 如果 exact = false,則週期為 93.5 ns(即,不大於請求值的最大週期)。 請注意,即使使用 exact = true,也可能/需要小於 1 ns 的某些舍入。 在以上示例中,請求 .period_length_ns = 94 且 exact = true,則硬體配置的週期 = 93.5 ns。

令 C 為給定 PWM 裝置的可能硬體配置的集合,由元組 (p, d, o) 組成,其中 p 是週期長度,d 是佔空比長度,o 是佔空比偏移量。

實現以下演算法來為給定請求 (p', d', o') 選擇硬體設定 (p, d, o) ∈ C,其中 exact = false

p = max( { ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C ∧ ṗ ≤ p' } ∪ { min({ ṗ | ∃ ḋ, ȯ : (ṗ, ḋ, ȯ) ∈ C }) })
d = max( { ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C ∧ ḋ ≤ d' } ∪ { min({ ḋ | ∃ ȯ : (p, ḋ, ȯ) ∈ C }) })
o = max( { ȯ | (p, d, ȯ) ∈ C ∧ ȯ ≤ o' } ∪ { min({ ȯ | (p, d, ȯ) ∈ C }) })

用文字描述:選擇的週期長度是不大於請求的週期長度的最大可能週期長度,如果不存在,則選擇最小的週期長度。 選擇的佔空比長度是與選擇的週期長度相容且不大於請求的佔空比長度的最大可能佔空比長度。 同樣,如果不存在這樣的值,則選擇與選擇的週期相容的最小佔空比長度。 之後,以相同的方式選擇與選擇的週期和佔空比長度相容的佔空比偏移量。

返回

成功時返回 0,如果由於確切的波形不可能而導致設定失敗,則返回 -EDOM(如果 exact 為 true),否則返回不同的負 errno 表示失敗。

上下文

可能睡眠。

int pwm_apply_might_sleep(struct pwm_device *pwm, const struct pwm_state *state)

原子地將新狀態應用於 PWM 裝置。 不能在原子上下文中使用。

引數

struct pwm_device *pwm

PWM 裝置

const struct pwm_state *state

要應用的新狀態

返回

成功時返回 0,否則返回負 errno

上下文

可能睡眠。

int pwm_apply_atomic(struct pwm_device *pwm, const struct pwm_state *state)

從原子上下文將新狀態應用於 PWM 裝置。 並非所有 PWM 裝置都支援此功能,請使用 pwm_might_sleep() 進行檢查。

引數

struct pwm_device *pwm

PWM 裝置

const struct pwm_state *state

要應用的新狀態

返回

成功時返回 0,否則返回負 errno

上下文

任何

int pwm_get_state_hw(struct pwm_device *pwm, struct pwm_state *state)

從硬體獲取當前 PWM 狀態

引數

struct pwm_device *pwm

PWM 裝置

struct pwm_state *state

用於填充當前 PWM 狀態的狀態

說明

pwm_get_state() 類似,但是從硬體而不是請求的狀態讀取當前 PWM 狀態。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

上下文

可能睡眠。

int pwm_adjust_config(struct pwm_device *pwm)

將當前 PWM 配置調整為 PWM 引數

引數

struct pwm_device *pwm

PWM 裝置

說明

此函式將把 PWM 配置調整為由 DT 或 PWM 查詢表提供的 PWM 引數。 這對於將引導載入程式配置調整為 Linux 配置特別有用。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

上下文

可能睡眠。

struct pwm_device *pwm_get(struct device *dev, const char *con_id)

查詢並請求 PWM 裝置

引數

struct device *dev

PWM 使用者的裝置

const char *con_id

使用者名稱

說明

首先嚐試使用 DT 進行查詢。 如果裝置不是從裝置樹例項化的,則透過板設定程式碼提供的表查詢 PWM 晶片和相對索引(請參見 pwm_add_table())。

找到 PWM 晶片後,將請求指定的 PWM 裝置並準備好使用。

返回

指向請求的 PWM 裝置的指標,如果失敗,則為 ERR_PTR()-編碼的錯誤程式碼。

void pwm_put(struct pwm_device *pwm)

釋放 PWM 裝置

引數

struct pwm_device *pwm

PWM 裝置

struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)

資源託管的 pwm_get()

引數

struct device *dev

PWM 使用者的裝置

const char *con_id

使用者名稱

說明

此函式的作用類似於 pwm_get(),但是獲取的 PWM 裝置將在驅動程式分離時自動釋放。

返回

指向請求的 PWM 裝置的指標,如果失敗,則為 ERR_PTR()-編碼的錯誤程式碼。

struct pwm_device *devm_fwnode_pwm_get(struct device *dev, struct fwnode_handle *fwnode, const char *con_id)

從韌體節點請求資源託管的 PWM

引數

struct device *dev

PWM 使用者的裝置

struct fwnode_handle *fwnode

從中獲取 PWM 的韌體節點

const char *con_id

使用者名稱

說明

返回從韌體節點解析的 PWM 裝置。 有關詳細說明,請參見 of_pwm_get() 和 acpi_pwm_get()。

返回

指向請求的 PWM 裝置的指標,如果失敗,則為 ERR_PTR()-編碼的錯誤程式碼。

int __pwmchip_add(struct pwm_chip *chip, struct module *owner)

註冊新的 PWM 晶片

引數

struct pwm_chip *chip

要新增的 PWM 晶片

struct module *owner

對提供晶片的模組的引用。

說明

註冊一個新的 PWM 晶片。 owner 應該是 THIS_MODULE,請使用 pwmchip_add 包裝器來正確地執行此操作。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

void pwmchip_remove(struct pwm_chip *chip)

移除 PWM 晶片

引數

struct pwm_chip *chip

要移除的 PWM 晶片

說明

移除 PWM 晶片。