Pengembangan driver perangkat Linux:Subsistem kontrol pin
Catatan Editor:Kernel Linux yang disematkan sudah memainkan peran penting dalam sistem yang disematkan dan terus tumbuh semakin penting dalam melayani beragam persyaratan Internet of Things (IoT). Pada gilirannya, driver perangkat menyediakan tautan penting antara aplikasi dan perangkat IoT itu sendiri. Di Linux Device Drivers Development, penulis John Madieu menawarkan tinjauan komprehensif tentang pengembangan driver ini, menggabungkan penjelasan mendetail dengan banyak contoh kode.
Kutipan ini, Bab 14 dari buku ini, memfokuskan kontrol pin dan GPIO — area yang sangat penting bagi pengembang sistem tertanam yang ingin berinteraksi dengan perangkat keras khusus. Angsuran pertama dari kutipan ini memperkenalkan subsistem kontrol pin.
Diadaptasi dari Pengembangan Driver Perangkat Linux, oleh John Madieu.
Bab 14. Kontrol Pin dan Subsistem GPIO Oleh John Madieu
Sebagian besar driver dan insinyur kernel Linux yang tertanam menulis menggunakan GPIO atau bermain dengan pin multiplexing. Dengan pin, maksud saya garis keluar komponen. SoC melakukan pin multipleks, artinya pin mungkin memiliki beberapa fungsi, misalnya, MX6QDL_PAD_SD3_DAT1 di arch/arm/boot/dts/imx6dl-pinfunc.h dapat berupa jalur data SD3 1, cts/rts UART1, Rx Flexcan2, atau GPIO biasa.
Mekanisme dimana seseorang memilih mode pin yang harus bekerja disebut pin muxing. Sistem yang bertanggung jawab untuk ini disebut pengontrol pin. Di bagian kedua bab ini, kita akan membahas Keluaran Masukan Tujuan Umum (GPIO ), yang merupakan fungsi (mode) khusus di mana pin dapat beroperasi.
Dalam bab ini, kita akan:
Telusuri subsistem kontrol pin, dan lihat bagaimana seseorang dapat mendeklarasikan nodenya di DT
Jelajahi antarmuka GPIO berbasis integer lama, serta API antarmuka berbasis deskriptor baru
Berurusan dengan GPIO yang dipetakan ke IRQ
Menangani antarmuka sysfs yang didedikasikan untuk GPIO
Subsistem kontrol pin
Kontrol pin (pinctrl ) subsistem memungkinkan pengelolaan pin muxing. Di DT, perangkat yang membutuhkan pin untuk dimultiplexing dengan cara tertentu harus mendeklarasikan konfigurasi kontrol pin yang mereka butuhkan.
Subsistem pinctrl menyediakan:
Pin multiplexing, yang memungkinkan untuk menggunakan kembali pin yang sama untuk tujuan yang berbeda, seperti satu pin menjadi pin UART TX, jalur GPIO, atau jalur data HSI. Multiplexing dapat memengaruhi kelompok pin atau pin individual.
Konfigurasi pin, menerapkan properti elektronik pin seperti pull-up, pull-down, kekuatan driver, periode debounce, dan sebagainya.
Tujuan buku ini terbatas pada penggunaan fungsi yang diekspor oleh driver pengontrol pin, dan bukan cara menulis driver pengontrol pin.
Pinctrl dan pohon perangkat
Pinctrl tidak lain adalah cara untuk mengumpulkan pin (tidak hanya GPIO), dan meneruskannya ke driver. Driver pengontrol pin bertanggung jawab untuk menguraikan deskripsi pin di DT dan menerapkan konfigurasinya dalam chip. Pengemudi biasanya membutuhkan satu set dua node bersarang untuk menggambarkan grup konfigurasi pin. Node pertama menjelaskan fungsi grup (untuk tujuan apa grup akan digunakan), node kedua menyimpan konfigurasi pin.
Bagaimana grup pin ditetapkan dalam DT sangat bergantung pada platform, dan dengan demikian driver pengontrol pin. Setiap status kontrol pin diberikan ID integer mulai dari 0 dan bersebelahan. Seseorang dapat menggunakan properti nama, yang akan dipetakan di atas ID, sehingga nama yang sama selalu menunjuk ke ID yang sama.
Setiap pengikatan perangkat klien sendiri menentukan kumpulan status yang harus ditentukan dalam simpul DT-nya, dan apakah akan menentukan kumpulan ID status yang harus disediakan, atau apakah akan menentukan kumpulan nama status yang harus disediakan. Bagaimanapun, simpul konfigurasi pin dapat ditetapkan ke perangkat melalui dua properti:
pinctrl- :Ini memungkinkan untuk memberikan daftar konfigurasi pinctrl yang diperlukan untuk status perangkat tertentu. Ini adalah daftar phandles, yang masing-masing menunjuk ke node konfigurasi pin. Node konfigurasi pin yang direferensikan ini harus merupakan node anak dari pengontrol pin yang mereka konfigurasikan. Beberapa entri mungkin ada dalam daftar ini sehingga beberapa pengontrol pin dapat dikonfigurasi, atau agar status dapat dibangun dari beberapa node untuk pengontrol pin tunggal, masing-masing berkontribusi bagian dari konfigurasi keseluruhan.
pinctrl-name :Ini memungkinkan untuk memberi nama setiap negara bagian dalam daftar. Entri daftar 0 mendefinisikan nama untuk ID status bilangan bulat 0, entri daftar 1 untuk ID status 1, dan seterusnya. ID negara bagian 0 biasanya diberi nama default . Daftar status standar dapat ditemukan di include/linux/pinctrl/pinctrl-state.h .
Berikut ini adalah kutipan dari DT, yang menunjukkan beberapa node perangkat, bersama dengan node kontrol pinnya:
Pada contoh sebelumnya, konfigurasi pin diberikan dalam bentuk . Misalnya:
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 0x80000000
MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09 mewakili fungsi pin, yang dalam hal ini adalah GPIO, dan 0x80000000 mewakili pengaturan pin. Untuk baris ini,
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D25__UART3_RX_DATA mewakili fungsi pin, yang merupakan garis RX dari UART3, dan 0x1b0b1 mewakili pengaturan.
Fungsi pin adalah makro yang nilainya bermakna untuk driver pengontrol pin saja. Ini umumnya didefinisikan dalam file header yang terletak di arch//boot/dts/ . Jika seseorang menggunakan UDOO quad, misalnya, yang memiliki i.MX6 quad core (ARM), header fungsi pin adalah arch/arm/boot/dts/imx6q-pinfunc.h . Berikut ini adalah makro yang sesuai dengan baris kelima dari pengontrol GPIO5:
dapat digunakan untuk mengatur hal-hal seperti pull-up, pull-down, penjaga, kekuatan drive, dan sebagainya. Bagaimana itu harus ditentukan tergantung pada pengikatan pengontrol pin, dan arti nilainya tergantung pada lembar data SoC, umumnya di bagian IOMUX. Pada i.MX6 IOMUXC, hanya lebih rendah dari 17 bit yang digunakan untuk tujuan ini.
Node sebelumnya ini dipanggil dari node khusus driver yang sesuai. Selain itu, pin ini dikonfigurasi selama inisialisasi driver yang sesuai. Sebelum memilih status grup pin, seseorang harus mendapatkan kontrol pin terlebih dahulu menggunakan fungsi pinctrl_get(), memanggil pinctrl_lookup_state() untuk memeriksa apakah status yang diminta ada atau tidak, dan terakhir pinctrl_select_state() untuk menerapkan status.
Berikut ini adalah contoh yang menunjukkan cara mendapatkan pincontrol dan menerapkan konfigurasi defaultnya:
Seseorang biasanya melakukan langkah-langkah seperti itu selama inisialisasi driver. Tempat yang cocok untuk kode ini bisa jadi dalam fungsi probe().
pinctrl_select_state() secara internal memanggil pinmux_enable_setting() , yang pada gilirannya memanggil pin_request() pada setiap pin di node kontrol pin.
Kontrol pin dapat dilepaskan dengan fungsi pinctrl_put(). Seseorang dapat menggunakan versi API yang dikelola sumber daya. Yang mengatakan, seseorang dapat menggunakan pinctrl_get_select(), diberi nama negara untuk dipilih, untuk mengonfigurasi pinmux. Fungsi tersebut didefinisikan di include/linux/pinctrl/consumer.h sebagai berikut:
di mana *name adalah nama negara bagian seperti yang tertulis di properti pinctrl-name. Jika nama negara adalah default , seseorang dapat memanggil fungsi pinctr_get_select_default(), yang merupakan pembungkus pinctl_get_select() :
Mari kita lihat contoh nyata dalam file dts khusus papan (am335x-evm.dts ):
dcan1:d_can@481d0000 { status =“oke”; pinctrl-names =“default”; pinctrl-0 =<&d_can1_pins>; };
Dan di driver yang sesuai:
pinctrl =devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev,”pin tidak dikonfigurasi dari driver”);
Inti kontrol pin akan secara otomatis mengklaim status pinctrl default untuk kami saat perangkat diperiksa. Jika seseorang mendefinisikan status init, inti pinctrl akan secara otomatis menyetel pinctrl ke status ini sebelum fungsi probe(), dan kemudian beralih ke status default setelah probe() (kecuali driver sudah secara eksplisit mengubah status).
John Madieu adalah seorang insinyur Linux dan kernel tertanam yang tinggal di Prancis, di Paris. Kegiatan utamanya terdiri dari pengembangan driver dan Board Support Packages (BSP) untuk perusahaan di domain seperti otomatisasi, transportasi, perawatan kesehatan, energi, dan militer. John bekerja di EXPEMB, sebuah perusahaan Prancis yang merupakan pionir dalam desain papan elektronik berbasis komputer-di-modul, dan dalam solusi Linux tertanam. Dia adalah penggemar open source dan sistem tertanam, yakin bahwa hanya dengan berbagi pengetahuan, seseorang dapat belajar lebih banyak.