• linux-kernel-4.4 移植 (3) 网卡移植


    开发环境:win10 64位 + VMware12 + Ubuntu14.04 32位

    工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi

    要移植的kernel版本:linux-4.4

    Tiny4412开发板硬件版本为

      底板:  Tiny4412SDK 1312B

      核心板:Tiny4412 - 1306

    ——————————————————————————————————————————————————————————

     1,查看原理图

    与整个DM9621相连的有三个口,DP1+和DM1-与USB4640连接传输数据。另有一个复位口,控制网卡使能,低电平有效。所以我们在配置设备树USB-HUB时, 需要将GPM2_4拉低。

    2,Patch

    diff --git a/include/linux/platform_data/usb4640.h b/include/linux/platform_data/usb4640.h
    new file mode 100644
    index 0000000..062a50c
    --- /dev/null
    +++ b/include/linux/platform_data/usb4640.h
    @@ -0,0 +1,24 @@
    +#ifndef __USB4640_H__
    +#define __USB4640_H__
    +
    +#define USB4640_NAME   "usb4640"
    
    +enum usb4640_mode {
    +       USB4640_MODE_UNKNOWN = 1,
    +       USB4640_MODE_HUB,
    +       USB4640_MODE_STANDBY,
    +};
    +
    +struct usb4640_platform_data {
    +       enum usb4640_mode       initial_mode;
    +#define USB4640_NAME   "usb4640"
    
    +enum usb4640_mode {
    +       USB4640_MODE_UNKNOWN = 1,
    +       USB4640_MODE_HUB,
    +       USB4640_MODE_STANDBY,
    +};
    +
    +struct usb4640_platform_data {
    +       enum usb4640_mode       initial_mode;
    +     int     gpio_reset;
    +};
    +
    +#endif
    diff --git a/include/dt-bindings/usb4640/usb4640.h b/include/dt-bindings/usb4640/usb4640.h
    new file mode 100644
    index 0000000..ef3e1e1
    --- /dev/null
    +++ b/include/dt-bindings/usb4640/usb4640.h
    @@ -0,0 +1,7 @@
    +#ifndef _DT_BINDINGS_USB4640
    +#define _DT_BINDINGS_USB4640
    +
    +#define USB4640_MODE_UNKNOWN   1
    +#define USB4640_MODE_HUB       2
    +#define USB4640_MODE_STANDBY   3
    +#endif
    diff --git a/drivers/usb/misc/usb4640.c b/drivers/usb/misc/usb4640.c
    new file mode 100644
    index 0000000..b7bc085
    --- /dev/null
    +++ b/drivers/usb/misc/usb4640.c
    @@ -0,0 +1,157 @@
    +/*
    + * Driver for SMSC USB4640 USB 2.0 hub controller driver
    + *
    + */
    +
    +#include <linux/gpio.h>
    +#include <linux/delay.h>
    +#include <linux/slab.h>
    +#include <linux/module.h>
    +#include <linux/of_gpio.h>
    +#include <linux/platform_device.h>
    +#include <linux/platform_data/usb4640.h>
    +
    +struct usb4640 {
    +       enum usb4640_mode       mode;
    +       struct device           *dev;
    +       int     gpio_reset;
    +};
    +
    +static int usb4640_reset(struct usb4640 *hub, int state)
    +{
    +       if (gpio_is_valid(hub->gpio_reset))
    +               gpio_set_value_cansleep(hub->gpio_reset, state);
    +
    +       /* Wait 1ms for hub logic to stabilize */
    +       if (state)
    +               usleep_range(1, 10);
    +
    +       return 0;
    +}
    +
    +static int usb4640_connect(struct usb4640 *hub)
    +{
    +       struct device *dev = hub->dev;
    +
    +       usb4640_reset(hub, 1);
    +       hub->mode = USB4640_MODE_HUB;
    +       dev_info(dev, "switched to HUB mode
    ");
    +
    +       return 0;
    +}
    +
    +static int usb4640_switch_mode(struct usb4640 *hub, enum usb4640_mode mode)
    +{
    +       struct device *dev = hub->dev;
    +       int err = 0;
    +
    +       switch (mode) {
    +       case USB4640_MODE_HUB:
    +               err = usb4640_connect(hub);
    +               break;
    +
    +       case USB4640_MODE_STANDBY:
    +               usb4640_reset(hub, 0);
    +               dev_info(dev, "switched to STANDBY mode
    ");
    +               break;
    +
    +       default:
    +               dev_err(dev, "unknown mode is requested
    ");
    +               err = -EINVAL;
    +               break;
    +       }
    +
    +       return err;
    +}
    +
    +
    +static int usb4640_probe(struct usb4640 *hub)
    +{
    +       struct device *dev = hub->dev;
    +       struct usb4640_platform_data *pdata = dev_get_platdata(dev);
    +       struct device_node *np = dev->of_node;
    +       int err;
    +       u32 mode = USB4640_MODE_HUB;
    +
    +       if (pdata) {
    +               hub->gpio_reset         = pdata->gpio_reset;
    +               hub->mode               = pdata->initial_mode;
    +       } else if (np) {
    +               hub->gpio_reset = of_get_named_gpio(np, "reset-gpios", 0);
    +               if (hub->gpio_reset == -EPROBE_DEFER)
    +                       return -EPROBE_DEFER;
    +               of_property_read_u32(np, "initial-mode", &mode);
    +               hub->mode = mode;
    +       }
    +
    +       if (gpio_is_valid(hub->gpio_reset)) {
    +               err = devm_gpio_request_one(dev, hub->gpio_reset,
    +                               GPIOF_OUT_INIT_LOW, "usb4640 reset");
    +               if (err) {
    +                       dev_err(dev,
    +                               "unable to request GPIO %d as reset pin (%d)
    ",
    +                               hub->gpio_reset, err);
    +                       return err;
    +               }
    +       } else
    +               dev_err(dev, "reset gpio is invalid: %d
    ", hub->gpio_reset);
    +
    +       usb4640_switch_mode(hub, hub->mode);
    +
    +       dev_info(dev, "%s: probed in %s mode
    ", __func__,
    +                       (hub->mode == USB4640_MODE_HUB) ? "hub" : "standby");
    +
    +       return 0;
    +}
    +
    +static int usb4640_platform_probe(struct platform_device *pdev)
    +{
    +       struct usb4640 *hub;
    +
    +       hub = devm_kzalloc(&pdev->dev, sizeof(struct usb4640), GFP_KERNEL);
    +       if (!hub)
    +               return -ENOMEM;
    +       hub->dev = &pdev->dev;
    +
    +       return usb4640_probe(hub);
    +}
    +
    +#ifdef CONFIG_OF
    +static const struct of_device_id usb4640_of_match[] = {
    +       { .compatible = "smsc,usb4640", },
    +       {},
    +};
    +MODULE_DEVICE_TABLE(of, usb4640_of_match);
    +#endif
    +
    +static struct platform_driver usb4640_platform_driver = {
    +       .driver = {
    +               .name = USB4640_NAME,
    +#ifdef CONFIG_OF
    +               .of_match_table = of_match_ptr(usb4640_of_match),
    +#endif
    +       },
    +       .probe          = usb4640_platform_probe,
    +};
    +
    +static int __init usb4640_init(void)
    +{
    +       int err;
    +
    +       err = platform_driver_register(&usb4640_platform_driver);
    +       if (err != 0)
    +               pr_err("usb4640: Failed to register platform driver: %d
    ",
    +                      err);
    +
    +       return 0;
    +}
    +module_init(usb4640_init);
    +
    +static void __exit usb4640_exit(void)
    +{
    +       platform_driver_unregister(&usb4640_platform_driver);
    +}
    +module_exit(usb4640_exit);
    +
    +MODULE_DESCRIPTION("USB4640 USB HUB driver");
    +MODULE_LICENSE("GPL");
    diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
    index 45fd4ac..98f81ed 100644
    --- a/drivers/usb/misc/Makefile
    +++ b/drivers/usb/misc/Makefile
    @@ -25,6 +25,9 @@ obj-$(CONFIG_USB_USS720)              += uss720.o
     obj-$(CONFIG_USB_SEVSEG)               += usbsevseg.o
     obj-$(CONFIG_USB_YUREX)                        += yurex.o
     obj-$(CONFIG_USB_HSIC_USB3503)         += usb3503.o
    +
    +obj-$(CONFIG_USB_HSIC_USB4640)         += usb4640.o
    +
     obj-$(CONFIG_USB_CHAOSKEY)             += chaoskey.o
     
     obj-$(CONFIG_USB_SISUSBVGA)            += sisusbvga/
    diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
    index f7a7fc2..9692ca5 100644
    --- a/drivers/usb/misc/Kconfig
    +++ b/drivers/usb/misc/Kconfig
    @@ -249,6 +249,11 @@ config USB_HSIC_USB3503
            help
              This option enables support for SMSC USB3503 HSIC to USB 2.0 Driver.
     
    +config USB_HSIC_USB4640
    +        tristate "USB4640 HSIC to USB20 Driver"
    +        help
    +            This option enables support for SMSC USB4640 HSIC to USB 2.0 Driver.
    +
     config USB_LINK_LAYER_TEST
            tristate "USB Link Layer Test driver"
            help
    diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos
    index 048ae67..948f2d9 100644
    --- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
    +++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
    @@ -14,6 +14,7 @@
     /dts-v1/;
     #include "exynos4412.dtsi"
     #include <dt-bindings/gpio/gpio.h>
    +#include <dt-bindings/usb4640/usb4640.h>
     
     / {
            model = "FriendlyARM TINY4412 board based on Exynos4412";
    @@ -21,13 +22,16 @@
     
            chosen {
                    stdout-path = &serial_0;
    -        bootargs="root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 init=
    -       };
    +     bootargs="root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 et hmac=1C:6F:65:34:51:7E init=/linuxrc ignore_loglevel earlyprink";
    + 
    +    };
    +
     
            memory {
    +               device_type = "memory";
                    reg = <0x40000000 0x40000000>;
            };
    -
    +    
            leds {
                    compatible = "gpio-leds";
     
    @@ -69,8 +73,17 @@
                            clock-frequency = <24000000>;
                    };
            };
    +
    +    usb-hub {
    +        compatible = "smsc,usb4640";
    +        reset-gpios = <&gpm2 4 GPIO_ACTIVE_LOW>;
    +        initial-mode = <USB4640_MODE_HUB>; 
    +        status = "okay";
    +    };
     };
     
    +
    +
     &rtc {
            status = "okay";
     };
    @@ -98,3 +111,47 @@
     &serial_3 {
            status = "okay";
     };
    +
    +&mshc_0 {
    +   pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
    +   pinctrl-names = "default";
    +   status = "okay";
    +     
    +   num-slots = <1>;
    +   broken-cd;
    +   card-detect-delay = <200>;
    +   samsung,dw-mshc-ciu-div = <3>;
    +   samsung,dw-mshc-sdr-timing = <2 3>;
    +   samsung,dw-mshc-ddr-timing = <1 2>;
    +   bus-width = <8>;
    +   cap-mmc-highspeed;
    +};
    +
    +
    +&exynos_usbphy {
    +    status = "okay";
    +};
    +
    +&ehci {
    +    status = "okay";
    +    port@0 {
    +        status = "okay";
    +    };
    +    port@1 {
    +        status = "okay";
    +    };
    +    port@2 {
    +        status = "okay";
    +    };
    +};
    +
    +&ohci {
    +    status = "okay";
    +    port@0 {
    +        status = "okay";
    +     };
    +};
    +
    +&hsotg {
    +    status = "okay";
    +};
    +
    diff --git a/tiny4412_defconfig b/tiny4412_defconfig
    index 91cba5b..178cea8 100644
    --- a/tiny4412_defconfig
    +++ b/tiny4412_defconfig
    @@ -1160,7 +1160,7 @@ CONFIG_USB_NET_CDCETHER=y
     CONFIG_USB_NET_CDC_NCM=y
     # CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
     # CONFIG_USB_NET_CDC_MBIM is not set
    -# CONFIG_USB_NET_DM9601 is not set
    +CONFIG_USB_NET_DM9601=y
     # CONFIG_USB_NET_SR9700 is not set
     # CONFIG_USB_NET_SR9800 is not set
     CONFIG_USB_NET_SMSC75XX=y
    @@ -2628,7 +2628,8 @@ CONFIG_USB_DWC2_DUAL_ROLE=y
     # CONFIG_USB_ISIGHTFW is not set
     # CONFIG_USB_YUREX is not set
     # CONFIG_USB_EZUSB_FX2 is not set
    -CONFIG_USB_HSIC_USB3503=y
    +# CONFIG_USB_HSIC_USB3503 is not set
    +CONFIG_USB_HSIC_USB4640=y
     # CONFIG_USB_LINK_LAYER_TEST is not set
     # CONFIG_USB_CHAOSKEY is not set

     结果:

    发现缺少IP地址

    [root@tiny4412:/]#ifconfig eth0 192.168.1.130

    完成。

  • 相关阅读:
    Visual C++6.0 调用Visual Basic 6.0写的Microsoft Communications Control(ActiveX)的使用疑难及解决办法
    Associating Icons with a Category 与 恶作剧软件 有关系吗?
    WPF/Silverlight Button Styles and Templates
    Notepad++ 备忘录一
    冥思苦想,木疙瘩也能崩出个豆:扯一下各大软件的用户体验
    生活小窍门。
    Bug验证:.Net 4 下,貌似发现一个bug。如果是真,.Net组的员工该打屁股。
    两台硬件和软件配置完全相同的机器A和B,现在要用系统自带的Copy功能把A上的一个文件,复制到B上。在哪台机器上执行程序,效率更高?
    WPF 遍历 DataGrid 每行的控件
    IE ActiveX Control 和RIA
  • 原文地址:https://www.cnblogs.com/chu-yi/p/10768690.html
Copyright © 2020-2023  润新知