基於tiny4412的Linux內核移植 -- MMA7660驅動移植(九)

来源:http://www.cnblogs.com/pengdonglin137/archive/2016/03/03/5240416.html
-Advertisement-
Play Games


作者信息

作者: 彭東林

郵箱:[email protected]

QQ:405728433

平臺簡介

開發板:tiny4412ADK + S700 + 4GB Flash

要移植的內核版本:Linux-4.4.0 (支持device tree)

u-boot版本:友善之臂自帶的 U-Boot 2010.12 (為支持uImage啟動,做了少許改動)

busybox版本:busybox 1.25

交叉編譯工具鏈: arm-none-linux-gnueabi-gcc

      (gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29))

摘要

    MMA7660是一個三軸加速度感測器,跟exynos4412之間使用I2C介面進行通信,同時MMA7660可以向exynos4412發起外部中斷。

    移植MMA7660驅動會涉及到device tree、I2C驅動、中斷、輸入子系統等幾個部分,tiny4412自帶的MMA7660驅動程式是不支持設備樹的,同時I2C驅動也沒有採用設備樹,所以主要的工作量就是將MMA7660和I2C驅動程式從非設備樹形式轉變為設備樹的形式。同時藉此機會,學習一下有設備樹的情況下的設備驅動(MMA7660和I2C)和中斷。

移植

一、原理圖

下麵是MMA7660的在底板原理圖:

image

     可以看到,使用的是第3個I2C控制器。

下麵是核心板:

  I2C:

image

   XEINT25:

image

二、tiny4412自帶的驅動

    tiny4412自帶的mma7660驅動並不是採用設備樹,但是可以作為我們的參考,在arch/arm/mach-exynos/mach-tiny4412.c中包含了mma7660的板級信息。

MMA7660的板級信息:

   1: #include <linux/mma7660.h>
   2: static struct mma7660_platform_data mma7660_pdata = {
   3:     .irq            = IRQ_EINT(25),
   4:     .poll_interval    = 100,
   5:     .input_fuzz        = 4,
   6:     .input_flat        = 4,
   7: };
   8:  
   9: static struct s3c2410_platform_i2c tiny4412_i2c3_data __initdata = {
  10:     .flags            = 0,
  11:     .bus_num        = 3,
  12:     .slave_addr        = 0x10,
  13:     .frequency        = 200*1000,
  14:     .sda_delay        = 100,
  15: };
  16:  
  17: static struct i2c_board_info i2c_devs3[] __initdata = {
  18:     {
  19:         I2C_BOARD_INFO("mma7660", 0x4c),
  20:         .platform_data = &mma7660_pdata,
  21:     },
  22: };
  23:  
  24: static void __init smdk4x12_machine_init(void)
  25: {
  26:     ... ...
  27:     s3c_i2c3_set_platdata(&tiny4412_i2c3_data);
  28:     i2c_register_board_info(3, i2c_devs3, ARRAY_SIZE(i2c_devs3));   // 註冊板級信息
  29:     ... ...
  30: }

其中,

從上面的信息我們可以知道:

MMA7660的器件地址是0x4c,I2C3的CLK信號新的頻率為200KHz。這兩個信息比較重要。MMA7660的驅動程式是linux-3.0.86/drivers/hwmon/mma7660.c。

I2C的板級信息:

在arch/arm/plat-samsung/dev-i2c3.c中:

   1: /* linux/arch/arm/plat-samsung/dev-i2c3.c
   2:  *
   3:  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
   4:  *        http://www.samsung.com/
   5:  *
   6:  * S5P series device definition for i2c device 3
   7:  *
   8:  * This program is free software; you can redistribute it and/or modify
   9:  * it under the terms of the GNU General Public License version 2 as
  10:  * published by the Free Software Foundation.
  11:  */
  12:  
  13: #include <linux/gfp.h>
  14: #include <linux/kernel.h>
  15: #include <linux/string.h>
  16: #include <linux/platform_device.h>
  17:  
  18: #include <mach/irqs.h>
  19: #include <mach/map.h>
  20:  
  21: #include <plat/regs-iic.h>
  22: #include <plat/iic.h>
  23: #include <plat/devs.h>
  24: #include <plat/cpu.h>
  25:  
  26: static struct resource s3c_i2c_resource[] = {
  27:     [0] = {
  28:         .start    = S3C_PA_IIC3,
  29:         .end    = S3C_PA_IIC3 + SZ_4K - 1,
  30:         .flags    = IORESOURCE_MEM,
  31:     },
  32:     [1] = {
  33:         .start    = IRQ_IIC3,
  34:         .end    = IRQ_IIC3,
  35:         .flags    = IORESOURCE_IRQ,
  36:     },
  37: };
  38:  
  39: struct platform_device s3c_device_i2c3 = {
  40:     .name        = "s3c2440-i2c",
  41:     .id        = 3,
  42:     .num_resources    = ARRAY_SIZE(s3c_i2c_resource),
  43:     .resource    = s3c_i2c_resource,
  44: };
  45:  
  46: void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
  47: {
  48:     struct s3c2410_platform_i2c *npd;
  49:  
  50:     if (!pd) {
  51:         pd = &default_i2c_data;
  52:         pd->bus_num = 3;
  53:     }
  54:  
  55:     npd = s3c_set_platdata(pd, sizeof(struct s3c2410_platform_i2c),
  56:                    &s3c_device_i2c3);
  57:  
  58:     if (!npd->cfg_gpio)
  59:         npd->cfg_gpio = s3c_i2c3_cfg_gpio;
  60: }

然後會在arch/arm/mach-exynos/mach-tiny4412.c中註冊:

   1: static struct platform_device *smdk4x12_devices[] __initdata = {
   2:     ... ...
   3:     &s3c_device_i2c3,
   4:     ... ...
   5: }
   6:  
   7: static void __init smdk4x12_machine_init(void)
   8: {
   9:     ... ...
  10:     platform_add_devices(smdk4x12_devices, ARRAY_SIZE(smdk4x12_devices));
  11:     ... ...
  12: }

I2C控制器對應的驅動是linux-3.0.86/drivers/i2c/busses/i2c-s3c2410.c。

三、移植

1、首先把MMA7660和I2C控制器的板級信息轉化為設備樹的形式,修改arch/arm/boot/dts/exynos4412-tiny4412.dts,添加MMA7660和I2C的硬體信息,可以參考內核文檔:Documentation/devicetree/bindings/i2c/i2c.txt和Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt,中斷資源的填寫可以參考內核文檔Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt。

   1: /* MMA7660FC  */
   2: &i2c_3 {
   3:     samsung,i2c-sda-delay = <100>;
   4:     samsung,i2c-slave-addr = <0x10>;
   5:     samsung,i2c-max-bus-freq = <200000>;
   6:     pinctrl-0 = <&i2c3_bus>;
   7:     pinctrl-names = "default";
   8:     status = "okay";
   9:  
  10:     mma7660@4c {
  11:         compatible = "freescale,mma7660";
  12:         reg = <0x4c>;
  13:         interrupt-parent = <&gpx3>;
  14:         interrupts = <1 2>;
  15:         poll_interval = <100>;
  16:         input_fuzz = <4>;
  17:         input_flat = <4>;
  18:         status = "okay";
  19:     };
  20: };

上面的信息基本上是把原來的板級信息搬過來。

第13行和第14行是設置中斷資源,參考Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt:

External GPIO and Wakeup Interrupts:
 
The controller supports two types of external interrupts over gpio. The first
is the external gpio interrupt and second is the external wakeup interrupts.
The difference between the two is that the external wakeup interrupts can be
used as system wakeup events.
 
A. External GPIO Interrupts: For supporting external gpio interrupts, the
   following properties should be specified in the pin-controller device node.
 
   - interrupt-parent: phandle of the interrupt parent to which the external
     GPIO interrupts are forwarded to.
   - interrupts: interrupt specifier for the controller. The format and value of
     the interrupt specifier depends on the interrupt parent for the controller.
 
   In addition, following properties must be present in node of every bank
   of pins supporting GPIO interrupts:
 
   - interrupt-controller: identifies the controller node as interrupt-parent.
   - #interrupt-cells: the value of this property should be 2.
     - First Cell: represents the external gpio interrupt number local to the
       external gpio interrupt space of the controller.
     - Second Cell: flags to identify the type of the interrupt
       - 1 = rising edge triggered
       - 2 = falling edge triggered
       - 3 = rising and falling edge triggered
       - 4 = high level triggered
       - 8 = low level triggered

對於interrupts = <1 2>,其中1表示GPX3_1,2表示的是下降沿觸發。

第2行的i2c_3是一個標號,i2c3的其他信息是在arch/arm/boot/dts/exynos4.dtsi中:

   1: i2c_3: i2c@13890000 {
   2:     #address-cells = <1>;
   3:     #size-cells = <0>;
   4:     compatible = "samsung,s3c2440-i2c";
   5:     reg = <0x13890000 0x100>;
   6:     interrupts = <0 61 0>;
   7:     clocks = <&clock CLK_I2C3>;
   8:     clock-names = "i2c";
   9:     pinctrl-names = "default";
  10:     pinctrl-0 = <&i2c3_bus>;
  11:     status = "disabled";
  12: };

第10行是設置GPIO的功能復用,i2c3_bus是在文件arch/arm/boot/dts/exynos4x12-pinctrl.dtsi中:

   1: i2c3_bus: i2c3-bus {
   2:     samsung,pins = "gpa1-2", "gpa1-3";
   3:     samsung,pin-function = <3>;
   4:     samsung,pin-pud = <3>;
   5:     samsung,pin-drv = <0>;
   6: };

那麼是在什麼時候解析這部分,然後設置功能復用的呢?這個以後再說。

2、填寫完板級信息,接下來就要移植驅動程式了,其中I2C控制器的驅動程式Linux內核已經寫好了,就是drivers/i2c/busses/i2c-s3c2410.c。MMA7660的驅動程式就需要我們自己移植了。

  • 註冊
   1: static const struct i2c_device_id mma7660_ids[] = {
   2:     { "mma7660", 0 },
   3:     { },
   4: };
   5: MODULE_DEVICE_TABLE(i2c, mma7660_ids);
   6:  
   7: #ifdef CONFIG_OF
   8: static const struct of_device_id mma7660_dt_match[] = {
   9:     { .compatible = "freescale,mma7660" },
  10:     { }
  11: };
  12: MODULE_DEVICE_TABLE(of, mma7660_dt_match);
  13: #endif
  14:  
  15: static struct i2c_driver mma7660_driver = {
  16:     .driver = {
  17:         .name    = MMA7660_NAME,
  18:         .pm    = &mma7660_pm_ops,
  19:         .of_match_table = of_match_ptr(mma7660_dt_match),
  20:     },
  21:     .probe        = mma7660_probe,
  22:     .remove        = mma7660_remove,
  23:     .id_table    = mma7660_ids,
  24: };
  25:  
  26: module_i2c_driver(mma7660_driver);
  • 解析設備樹
   1: static struct mma7660_platform_data *mma7660_parse_dt(struct device *dev)
   2: {
   3:     struct mma7660_platform_data *pdata;
   4:     struct device_node *np = dev->of_node;
   5:  
   6:     if (!np)
   7:         return NULL;
   8:  
   9:     pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  10:     if (!pdata) {
  11:         dev_err(dev, "failed to allocate platform data\n");
  12:         return NULL;
  13:     }
  14:  
  15:     if (of_property_read_u32(np, "poll_interval", &pdata->poll_interval)) {
  16:         dev_err(dev, "failed to get poll_interval property\n");
  17:         return NULL;
  18:     }
  19:  
  20:     if (of_property_read_u32(np, "input_fuzz", &pdata->input_fuzz)) {
  21:         dev_err(dev, "failed to get input_fuzz property\n");
  22:         return NULL;
  23:     }
  24:  
  25:     if (of_property_read_u32(np, "input_flat", &pdata->input_flat)) {
  26:         dev_err(dev, "failed to get input_flat property\n");
  27:         return NULL;
  28:     }
  29:  
  30:     return pdata;
  31: }

關於這部分我已經把代碼上傳到github上了,下載方法:

git clone https://github.com/pengdonglin137/linux-4.4_tiny4412.git -b port_to_tiny4412

測試

   1: [root@tiny4412 root]# cd /sys/bus/i2c/devices/3-004c/
   2: [root@tiny4412 3-004c]# ls
   3: all_axis_g   input        of_node      subsystem    x_axis_g
   4: driver       modalias     power        tilt_status  y_axis_g
   5: hwmon        name         registers    uevent       z_axis_g
   6: [root@tiny4412 3-004c]# cat all_axis_g 
   7:   2,   0,  22
   8: [root@tiny4412 3-004c]# cat registers 
   9: REG: 0x00 = 0x03 ...... [ 0000 0011 ]
  10: REG: 0x01 = 0x01 ...... [ 0000 0001 ]
  11: REG: 0x02 = 0x16 ...... [ 0001 0110 ]
  12: REG: 0x03 = 0x01 ...... [ 0000 0001 ]
  13: REG: 0x04 = 0x02 ...... [ 0000 0010 ]
  14: REG: 0x05 = 0xa0 ...... [ 1010 0000 ]
  15: REG: 0x06 = 0xe7 ...... [ 1110 0111 ]
  16: REG: 0x07 = 0x59 ...... [ 0101 1001 ]
  17: REG: 0x08 = 0x49 ...... [ 0100 1001 ]
  18: REG: 0x09 = 0x04 ...... [ 0000 0100 ]
  19: REG: 0x0a = 0x0f ...... [ 0000 1111 ]

用hexdump看看上報的事件:

   1: [root@tiny4412 ]# hexdump /dev/input/event0 
   2: 0000000 0013 0000 9b6a 0001 0003 0002 0015 0000
   3: 0000010 0013 0000 9b6a 0001 0000 0000 0000 0000
   4: 0000020 0013 0000 4015 0009 0003 0000 0002 0000
   5: 0000030 0013 0000 4015 0009 0000 0000 0000 0000
   6: 0000040 0018 0000 c6b5 000a 0003 0000 0004 0000
   7: 0000050 0018 0000 c6b5 000a 0000 0000 0000 0000
   8: 0000060 0019 0000 9ef7 0001 0003 0000 0006 0000
   9: 0000070 0019 0000 9ef7 0001 0000 0000 0000 0000
  10: 0000080 0019 0000 c6b3 000a 0003 0000 0005 0000
  11: 0000090 0019 0000 c6b3 000a 0000 0000 0000 0000
  12: 00000a0 0019 0000 d3f0 000d 0003 0000 0004 0000
  13: 00000b0 0019 0000 d3f0 000d 0000 0000 0000 0000
  14: 00000c0 001a 0000 25c1 0003 0003 0000 0003 0000
  15: 00000d0 001a 0000 25c1 0003 0000 0000 0000 0000
  16: 00000e0 001a 0000 32d0 0006 0003 0000 0002 0000
  17: 00000f0 001a 0000 32d0 0006 0000 0000 0000 0000
  18: 0000100 001a 0000 b980 0007 0003 0000 0001 0000
  19: 0000110 001a 0000 b980 0007 0000 0000 0000 0000

未完待續…


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當資料庫出現嚴重的性能問題或者hang了的時候,伺服器端sqlplus也無法連接時,此時如果想獲取資料庫當前的狀態信息,以便事後診斷,那麼我們非常需要通過systemstate dump來知道進程在做什麼,在等待什麼,誰是資源的持有者,誰阻塞了別人。在出現上述問題時,及時收集systemstate ...
  • 一、簡介 Redis的啟動也就是main函數的執行,程式的入口在redis.c中,啟動流程: 1. 初始化預設伺服器配置,如果是sentinel模式還需進行額外的配置 2. 修改配置文件或配置選項,這其中包括處理諸如-h/--help,-v/--version,--test-memory的特殊選項,
  • 最近遇到一個很有意思的使用環境,操作人員將所有的網站應用內容投放到共用存儲裡面,並且使用微軟的SMB協議將其以CIFS的方式共用出來,使用Windows Server 2008 R2的IIS將其連接起來。在多IIS主機的情況下,實現一次部署,多點生效的效果。 不過在使用的時候遇到了一些問題,在漢語世
  • 藍牙Bluetooth技術以及廣泛的應用於各種設備,並將繼續在物聯網IoT領域擔任重要角色。下麵搜集整理了一些關於藍牙技術的小知識,以備參考。藍牙Bluetooth技術始創於1994年,其名字來源於10世紀時的一位丹麥國王Harold Bluetooth,他統一了現在的挪威、瑞典和丹麥地區,以他的名...
  • 阿裡雲 Ubuntu 14.*上搭建laravel環境 之前做項目時都是搭建在自己的伺服器上,可是自己的那個伺服器是很久以前一點點配置好的,也是各種百度,該忘記的都忘了, 所以前一段在客戶的阿裡雲Ubuntu上搭建項目時發現又出了問題, laravel框架連接mysql報錯,具體錯誤碼記不住了,大概
  • 系統來自系統媽:http://www.xitongma.com/ 系統概述 蘿蔔家園GHOST win7 64位裝機旗艦版加快“網上鄰居”共用速度;取消不需要的網路服務組件,系統支持Windows安裝,可以在Windows中一鍵安裝了,方便了不會COMS設置和GHOST的人。集成了自2015年流行的
  • 前言:apt-get在安裝大多數包時是沒有問題的,但有些時候用apt-get命令安裝包出現錯誤提示如:the following packages have unmet dependencies(下列軟體包存在未滿足的依賴關係),通常可以採取更新軟體源的方法,這樣一般可以解決大多數軟體包安裝問題,但
  • 本文轉載自:http://blog.chinaunix.net/uid-24945116-id-83893.html 學習啦! asmlinkage是個巨集,使用它是為了保持參數在stack中。因為從彙編語言到C語言代碼參數的傳遞是通過stack的,它也可能從stack中得到一些不需要的參數。Asml
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...