LP5521/LP5523/LP55231/LP5562/LP8501 通用驅動

作者: Milo(Woogyom) Kim <milo.kim@ti.com>

描述

LP5521、LP5523/55231、LP5562 和 LP8501 具有以下共同特性。

透過 I2C 裝置初始化/取消初始化進行暫存器訪問 為多個輸出通道建立 LED 類裝置 用於執行 LED 模式的裝置屬性的使用者空間介面 用於執行 LED 模式的程式記憶體

LP55xx 通用驅動程式使用匯出的函式提供這些特性。

lp55xx_init_device() / lp55xx_deinit_device() lp55xx_register_leds() / lp55xx_unregister_leds() lp55xx_regsister_sysfs() / lp55xx_unregister_sysfs()

( 驅動程式結構資料 )

在 lp55xx 通用驅動程式中,使用了兩種不同的資料結構。

  • lp55xx_led

    控制多個輸出 LED 通道,例如 LED 電流、通道索引。

  • lp55xx_chip

    通用晶片控制,如 I2C 和平臺數據。

例如,LP5521 最多有 3 個 LED 通道。LP5523/55231 有 9 個輸出通道

lp55xx_chip for LP5521 ... lp55xx_led #1
                           lp55xx_led #2
                           lp55xx_led #3

lp55xx_chip for LP5523 ... lp55xx_led #1
                           lp55xx_led #2
                                 .
                                 .
                           lp55xx_led #9

( 晶片相關程式碼 )

為了支援特定於裝置的配置,使用了特殊的結構 ‘lpxx_device_config’。

  • 最大通道數

  • 復位命令、晶片使能命令

  • 晶片特定初始化

  • 亮度控制暫存器訪問

  • 設定 LED 輸出電流

  • 用於執行模式的程式記憶體地址訪問

  • 額外的裝置特定屬性

( 韌體介面 )

LP55xx 系列裝置具有內部程式儲存器,用於執行各種 LED 模式。

此模式資料儲存為使用者空間中的檔案,或透過 I2C 將十六進位制位元組字串寫入儲存器。

LP55xx 通用驅動程式支援韌體介面。

LP55xx 晶片有三個程式引擎。

要載入和執行模式,程式設計序列如下。

  1. 選擇一個引擎編號 (1/2/3)

  2. 模式更改為載入

  3. 將模式資料寫入選定區域

  4. 模式更改為執行

LP55xx 通用驅動程式提供如下簡單介面。

select_engine

選擇哪個引擎用於執行程式

run_engine

啟動透過韌體介面載入的程式

firmware

載入程式資料

對於 LP5523,需要一個額外的命令 ‘enginex_leds’。它用於選擇每個引擎編號的 LED 輸出。更多詳細資訊,請參考 ‘lp5523 的核心驅動程式’。

例如,在 LP5521 的引擎 #1 中執行閃爍模式

echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5521/loading
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
echo 0 > /sys/class/firmware/lp5521/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine

例如,在 LP55231 的引擎 #3 中執行閃爍模式

兩個 LED 被配置為模式輸出通道

echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp55231/loading
echo "9d0740ff7e0040007e00a0010000" > /sys/class/firmware/lp55231/data
echo 0 > /sys/class/firmware/lp55231/loading
echo "000001100" > /sys/bus/i2c/devices/xxxx/engine3_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine

同時啟動引擎 #2 和 #3 中的閃爍模式

for idx in 2 3
do
echo $idx > /sys/class/leds/red/device/select_engine
sleep 0.1
echo 1 > /sys/class/firmware/lp5521/loading
echo "4000600040FF6000" > /sys/class/firmware/lp5521/data
echo 0 > /sys/class/firmware/lp5521/loading
done
echo 1 > /sys/class/leds/red/device/run_engine

這是 LP5523 的另一個例子。

完整的 LED 字串由 ‘engine2_leds’ 選擇

echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp5523/loading
echo "9d80400004ff05ff437f0000" > /sys/class/firmware/lp5523/data
echo 0 > /sys/class/firmware/lp5523/loading
echo "111111111" > /sys/bus/i2c/devices/xxxx/engine2_leds
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine

一旦 ‘loading’ 設定為 0,註冊的回撥函式就會被呼叫。在回撥函式內部,載入選定的引擎並更新儲存器。要執行程式設計的模式,應啟用 ‘run_engine’ 屬性。

LP8501 的模式序列與 LP5523 相似。

但是模式資料是特定的。

示例 1) 使用引擎 1

echo 1 > /sys/bus/i2c/devices/xxxx/select_engine
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
echo 1 > /sys/bus/i2c/devices/xxxx/run_engine

示例 2) 同時使用引擎 2 和 3

echo 2 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0140ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 3 > /sys/bus/i2c/devices/xxxx/select_engine
sleep 1
echo 1 > /sys/class/firmware/lp8501/loading
echo "9d0340ff7e0040007e00a001c000" > /sys/class/firmware/lp8501/data
echo 0 > /sys/class/firmware/lp8501/loading
sleep 1
echo 1 > /sys/class/leds/d1/device/run_engine

( ‘run_engine’ 和 ‘firmware_cb’ )

執行程式資料的序列是通用的。

但是每個裝置都有自己的特定命令的暫存器地址。

為了支援這一點,‘run_engine’ 和 ‘firmware_cb’ 在每個驅動程式中都是可配置的。

run_engine

控制選定的引擎

firmware_cb

載入韌體完成後,執行回撥函式。

用於載入和更新程式儲存器的晶片特定命令。

( 預定義的模式資料 )

如果沒有韌體介面,LP55xx 驅動程式提供了另一種載入 LED 模式的方法。即 ‘預定義’ 模式。

預定義的模式在平臺數據中定義,如果需要,透過 sysfs 載入它(或它們)。

要使用預定義模式的概念,應配置 ‘patterns’ 和 ‘num_patterns’。

預定義模式資料的示例

/* mode_1: blinking data */
static const u8 mode_1[] = {
              0x40, 0x00, 0x60, 0x00, 0x40, 0xFF, 0x60, 0x00,
              };

/* mode_2: always on */
static const u8 mode_2[] = { 0x40, 0xFF, };

struct lp55xx_predef_pattern board_led_patterns[] = {
      {
              .r = mode_1,
              .size_r = ARRAY_SIZE(mode_1),
      },
      {
              .b = mode_2,
              .size_b = ARRAY_SIZE(mode_2),
      },
}

struct lp55xx_platform_data lp5562_pdata = {
...
      .patterns      = board_led_patterns,
      .num_patterns  = ARRAY_SIZE(board_led_patterns),
};

然後,可以透過 sysfs 執行 mode_1 和 mode_2

echo 1 > /sys/bus/i2c/devices/xxxx/led_pattern    # red blinking LED pattern
echo 2 > /sys/bus/i2c/devices/xxxx/led_pattern    # blue LED always on

停止執行模式

echo 0 > /sys/bus/i2c/devices/xxxx/led_pattern