当前位置:   article > 正文

RK3568移远4G模块EC20_qlril

qlril

1 DTS

本dts的内容不是必须的,也可以自己手动拉gpio去操控。

  1. rk_modem: rk-modem {
  2. compatible="4g-modem-platdata";
  3. 4G,vbat-gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
  4. //4G,power-gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_LOW>;
  5. 4G,reset-gpio = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>;
  6. status = "okay";
  7. };

对应的驱动为:kernel/drivers/net/lte/lte_rm310.c

2 内核驱动

新一点的内核(包含3568的4.19)都是已经包含了移远的option驱动的,无需再添加vid和pid。但是零包机制、电源管理以及第四个用于usbnet的口相关的代码还是有必要加上去的。即:

  1. kernel/drivers/usb/serial/option.c
  2. static struct usb_serial_driver option_1port_device = {
  3. .driver = {
  4. .owner = THIS_MODULE,
  5. .name = "option1",
  6. },
  7. .description = "GSM modem (1-port)",
  8. .id_table = option_ids,
  9. .num_ports = 1,
  10. .probe = option_probe,
  11. .open = usb_wwan_open,
  12. .close = usb_wwan_close,
  13. .dtr_rts = usb_wwan_dtr_rts,
  14. .write = usb_wwan_write,
  15. .write_room = usb_wwan_write_room,
  16. .chars_in_buffer = usb_wwan_chars_in_buffer,
  17. .tiocmget = usb_wwan_tiocmget,
  18. .tiocmset = usb_wwan_tiocmset,
  19. .ioctl = usb_wwan_ioctl,
  20. .attach = option_attach,
  21. .release = option_release,
  22. .port_probe = usb_wwan_port_probe,
  23. .port_remove = usb_wwan_port_remove,
  24. .read_int_callback = option_instat_callback,
  25. #ifdef CONFIG_PM
  26. .suspend = usb_wwan_suspend,
  27. .resume = usb_wwan_resume,
  28. +#if 1 //Added by Quectel
  29. + .reset_resume = usb_wwan_resume,
  30. +#endif
  31. #endif
  32. };
  33. static int option_probe(struct usb_serial *serial,
  34. const struct usb_device_id *id)
  35. {
  36. struct usb_interface_descriptor *iface_desc =
  37. &serial->interface->cur_altsetting->desc;
  38. unsigned long device_flags = id->driver_info;
  39. /* Never bind to the CD-Rom emulation interface */
  40. if (iface_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE)
  41. return -ENODEV;
  42. /*
  43. * Don't bind reserved interfaces (like network ones) which often have
  44. * the same class/subclass/protocol as the serial interfaces. Look at
  45. * the Windows driver .INF files for reserved interface numbers.
  46. */
  47. if (iface_is_reserved(device_flags, iface_desc->bInterfaceNumber))
  48. return -ENODEV;
  49. /*
  50. * Allow matching on bNumEndpoints for devices whose interface numbers
  51. * can change (e.g. Quectel EP06).
  52. */
  53. if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2)
  54. return -ENODEV;
  55. +#if 1 //Added by Quectel
  56. + if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
  57. + __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
  58. + struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;
  59. + if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) {
  60. + //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
  61. + return -ENODEV;
  62. + }
  63. + if ((idProduct&0xF000) == 0x0000) {
  64. + //MDM interface 4 is QMI
  65. + if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3
  66. + && intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol
  67. + == 0xFF)
  68. + return -ENODEV;
  69. + }
  70. + }
  71. +#endif
  72. /* Store the device flags so we can use them during attach. */
  73. usb_set_serial_data(serial, (void *)device_flags);
  74. return 0;
  75. }
  1. rk3568/kernel/drivers/usb/serial/usb_wwan.c
  2. static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
  3. int endpoint,
  4. int dir, void *ctx, char *buf, int len,
  5. void (*callback) (struct urb *))
  6. {
  7. struct usb_serial *serial = port->serial;
  8. struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial);
  9. struct urb *urb;
  10. struct usb_device_descriptor *desc = &serial->dev->descriptor;
  11. urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
  12. if (!urb)
  13. return NULL;
  14. usb_fill_bulk_urb(urb, serial->dev,
  15. usb_sndbulkpipe(serial->dev, endpoint) | dir,
  16. buf, len, callback, ctx);
  17. if (intfdata->use_zlp && dir == USB_DIR_OUT)
  18. urb->transfer_flags |= URB_ZERO_PACKET;
  19. if (dir == USB_DIR_OUT) {
  20. if ((desc->idVendor == cpu_to_le16(0x1286) &&
  21. desc->idProduct == cpu_to_le16(0x4e3c)))
  22. urb->transfer_flags |= URB_ZERO_PACKET;
  23. }
  24. +#if 1 //Added by Quectel for zero packet
  25. + if (dir == USB_DIR_OUT) {
  26. + struct usb_device_descriptor *desc = &serial->dev->descriptor;
  27. + if (desc->idVendor == cpu_to_le16(0x2C7C))
  28. + urb->transfer_flags |= URB_ZERO_PACKET;
  29. + }
  30. +#endif
  31. return urb;
  32. }

添加好虚拟出的各个串口后,要加入usbnet的驱动,可以使用GobiNet或者wwan。Gobinet是以前Linux内核没有添加相关驱动时的产物。目前使用wwan比较多。找到移远提供的qmai_wwan_q.c放入kernel/drivers/net/usb文件夹下,并修改Makefile:

  1. +obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan_q.o #最好放在qmi_wwan.o之前
  2. obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o

此驱动会生成wwan0(用ifconfig -a可以看到),以及/dev/cdc-wdm0设备。在Android中,需要修改部分代码才可以添加此设备:

  1. rk3568/system/core/init/devices.cpp
  2. void DeviceHandler::HandleUevent(const Uevent& uevent) {
  3. ...
  4. if (uevent.subsystem == "block") {
  5. block = true;
  6. devpath = "/dev/block/" + Basename(uevent.path);
  7. if (StartsWith(uevent.path, "/devices")) {
  8. links = GetBlockDeviceSymlinks(uevent);
  9. }
  10. } else if (const auto subsystem =
  11. std::find(subsystems_.cbegin(), subsystems_.cend(), uevent.subsystem);
  12. subsystem != subsystems_.cend()) {
  13. devpath = subsystem->ParseDevPath(uevent);
  14. } else if (uevent.subsystem == "usb") {
  15. if (!uevent.device_name.empty()) {
  16. devpath = "/dev/" + uevent.device_name;
  17. } else {
  18. // This imitates the file system that would be created
  19. // if we were using devfs instead.
  20. // Minors are broken up into groups of 128, starting at "001"
  21. int bus_id = uevent.minor / 128 + 1;
  22. int device_id = uevent.minor % 128 + 1;
  23. devpath = StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id);
  24. }
  25. +#if 1 // add by quectel for mknod /dev/cdc-wdm0
  26. + } else if(uevent.subsystem == "usbmisc" && !uevent.device_name.empty()){
  27. + devpath = "/dev/" + uevent.device_name;
  28. +#endif
  29. } else if (StartsWith(uevent.subsystem, "usb")) {
  30. // ignore other USB events
  31. return;
  32. } else {
  33. devpath = "/dev/" + Basename(uevent.path);
  34. }
  35. ...
  36. }

至于ECM等驱动也都是usbnet使用的,可以选择不添加。

3 Android

3.1 复制文件

首先要找到FAE要到适合自己android版本的对应的资料,其中包括文档、ril库等。

将libreference-ril.so拷贝并改名为:vendor/rockchip/common/phone/lib/libreference-ril-quel.so

将ql-ril.conf拷贝至:vendor/rockchip/common/phone/lib/ql-ril.conf

3.2 设置资源文件将复制的目标路径

  1. rk3568/vendor/rockchip/common/phone/phone.mk
  2. #########################################################
  3. # 3G Dongle SUPPORT
  4. #########################################################
  5. #PRODUCT_COPY_FILES += \
  6. $(CUR_PATH)/phone/etc/ppp/ip-down:system/etc/ppp/ip-down \
  7. $(CUR_PATH)/phone/etc/ppp/ip-up:system/etc/ppp/ip-up \
  8. $(CUR_PATH)/phone/etc/ppp/call-pppd:system/etc/ppp/call-pppd \
  9. $(CUR_PATH)/phone/etc/operator_table:system/etc/operator_table
  10. PRODUCT_COPY_FILES += \
  11. $(CUR_PATH)/phone/lib/libreference-ril-quel.so:vendor/lib64/libreference-ril-quel.so \
  12. $(CUR_PATH)/phone/lib/ql-ril.conf:system/etc/ql-ril.conf

3.3 SELINUX和rild服务

selinux部分需要注意的是通常文件最后需要有一个空行作为结尾。

  1. device/rockchip/common/ueventd.rockchip.rc
  2. +/dev/ttyACM* 0660 radio radio
  3. +/dev/cdc-wdm* 0660 radio radio
  4. +/dev/qcqmi* 0660 radio radio
  5. +/dev/cdc-acm* 0660 radio radio
  6. +/dev/mhi_DUN 0660 radio radio
  7. +/dev/mhi_DIAG 0660 radio radio
  8. +/dev/mhi_BHI 0660 radio radio
  9. +/dev/mhi_LOOPBACK 0660 radio radio
  10. +/dev/mhi_QMI0 0660 radio radio
  11. +
  1. device/rockchip/common/sepolicy/private/file_contexts
  2. +/dev/ttyUSB[0-9] u:object_r:radio_device:s0
  3. +/dev/ttyACM[0-9] u:object_r:radio_device:s0
  4. +/dev/cdc-wdm[0-9] u:object_r:radio_device:s0
  5. +/dev/qcqmi[0-9] u:object_r:radio_device:s0
  6. +/vendor/bin/hw/rild u:object_r:rild_exec:s0
  7. +/dev/socket/rildOemHook u:object_r:rild_socket:s0
  8. +
  9. +#pcie
  10. +/dev/mhi_DUN u:object_r:radio_device:s0
  11. +/dev/mhi_DIAG u:object_r:radio_device:s0
  12. +/dev/mhi_BHI u:object_r:radio_device:s0
  13. +/dev/mhi_LOOPBACK u:object_r:radio_device:s0
  14. +/dev/mhi_QMI0 u:object_r:radio_device:s0
  15. +
  1. system/sepolicy/vendor/rild.te
  2. +allow rild self:packet_socket { create bind write read };
  3. +

对应rild可以修改为:

  1. rk3568/hardware/ril/rild/rild.rc
  2. -#service vendor.ril-daemon /vendor/bin/hw/rild
  3. -# class main
  4. -# user radio
  5. -# group radio cache inet misc audio log readproc wakelock
  6. -# capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
  7. +service ril-daemon /vendor/bin/hw/rild -l /vendor/lib64/libreference-ril-quel.so
  8. + class main
  9. + user radio
  10. + group radio cache inet misc audio sdcard_rw log
  11. + capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW

3.4 修改BoardConfig.mk

SDK默认4G和dongle是关闭的,需要开启:

  1. device/rockchip/common/BoardConfig.mk
  2. -BOARD_HAS_RK_4G_MODEM ?= false
  3. +BOARD_HAS_RK_4G_MODEM ?= true
  4. -BOARD_HAVE_DONGLE ?= false
  5. +BOARD_HAVE_DONGLE ?= true
  1. external/usb_modeswitch/usb_dongle/Android.mk
  2. -#common_local_tidy_flags := -warnings-as-errors=clang-analyzer-security*,cert-*

3.5 修改device.mk

  1. rk3568/device/rockchip/rk356x/device.mk
  2. PRODUCT_PROPERTY_OVERRIDES += \
  3. ro.ril.ecclist=112,911 \
  4. ro.opengles.version=196610 \
  5. wifi.interface=wlan0 \
  6. + rild.libpath=/vendor/lib64/libreference-ril-quel.so \
  7. + rild.libargs=-d /dev/ttyUSB2 \
  1. rk3568/device/rockchip/common/device.mk
  2. ifeq ($(strip $(BOARD_HAS_RK_4G_MODEM)),true)
  3. PRODUCT_PACKAGES += \
  4. CarrierDefaultApp \
  5. CarrierConfig \
  6. rild \
  7. - librk-ril\
  8. + libreference-ril-quel \
  9. dhcpcd
  10. PRODUCT_COPY_FILES += vendor/rockchip/common/phone/etc/apns-full-conf.xml:$(TARGET_COPY_OUT_PRODUCT)/etc/apns-conf.xml
  11. PRODUCT_PACKAGES += \
  12. android.hardware.radio@1.2-radio-service \
  13. android.hardware.radio.config@1.0-service
  14. PRODUCT_PROPERTY_OVERRIDES += \
  15. ro.boot.noril=false \
  16. ro.telephony.default_network=9
  17. ifeq ($(strip $(TARGET_ARCH)), arm64)
  18. PRODUCT_PROPERTY_OVERRIDES += \
  19. - vendor.rild.libpath=/vendor/lib64/librk-ril.so
  20. + vendor.rild.libpath=/vendor/lib64/libreference-ril-quel.so

3.6 修改manifest.xml

  1. device/rockchip/common/4g_modem/manifest.xml
  2. <hal format="hidl">
  3. <name>android.hardware.radio.deprecated</name>
  4. <transport>hwbinder</transport>
  5. <version>1.0</version>
  6. <interface>
  7. <name>IOemHook</name>
  8. <instance>slot1</instance>
  9. </interface>
  10. </hal>
  11. <hal format="hidl">
  12. - <name>android.hardware.radio.config</name>
  13. + <name>android.hardware.radio</name>
  14. + <transport>hwbinder</transport>
  15. + <version>1.0</version>
  16. + <interface>
  17. - <name>IRadioConfig</name>
  18. + <name>IRadio</name>
  19. - <instance>default</instance>
  20. + <instance>slot1</instance>
  21. + </interface>
  22. </hal>
  23. </manifest>

3.7 启动脚本去掉ril-daemon

  1. device/rockchip/common/init.rk30board.rc
  2. # for telephony function
  3. -#on property:ro.boot.noril=true
  4. -# setprop ro.radio.noril true
  5. -# stop ril-daemon

3.8使能电话进程

3.8.1 设置→网络和互联网里没有“移动网络”选项

  1. rk3568/device/rockchip/rk356x/overlay/frameworks/base/core/res/res/values/config.xml
  2. <string-array translatable="false" name="networkAttributes">
  3. <item>"wifi,1,1,2,-1,true"</item>
  4. + <item>"mobile,0,0,0,-1,true"</item>
  5. + <item>"mobile_mms,2,0,2,60000,false"</item>
  6. + <item>"mobile_supl,3,0,2,60000,true"</item>
  7. + <item>"mobile_dun,4,0,2,60000,true"</item>
  8. + <item>"mobile_hipri,5,0,3,60000,true"</item>
  9. + <item>"mobile_fota,10,0,2,60000,true"</item>
  10. + <item>"mobile_ims,11,0,2,60000,true"</item>
  11. + <item>"mobile_cbs,12,0,2,60000,true"</item>
  12. <item>"bluetooth,7,7,0,-1,true"</item>
  13. <item>"ethernet,9,9,9,-1,true"</item>
  14. </string-array>

3.8.2 移动网络里没有APN选项

  1. rk3568/device/rockchip/common/overlay/frameworks/base/core/res/res/values/config.xml
  2. -<bool name="config_voice_capable">false</bool>
  3. +<bool name="config_voice_capable">true</bool>

3.8.3 移动信号图无信号

  1. rk3568/vendor/rockchip/common/phone/lib/ql-ril.conf
  2. # 打开如下选项
  3. LTE_Is_Report_SignalStrength=1

4 调试方式

4.1 内核

  1. ls /dev/ | grep ttyUSB // 可以看到ttyUSB0-3说明成功注册上option驱动,其中/dev/ttyUSB2AT指令口,可以收发AT指令。
  2. ifconfig -a //如果可以看到wwan0则成功注册了 qmi_wwan驱动
  1. # 如果正在运行rild可能导致抢AT指令资源,可以通过stop ril-daemon来先停止此服务
  2. # AT指令简单的测试
  3. > microcom /dev/ttyUSB2
  4. ate1
  5. AT
  6. OK //看到OK说明AT指令收发成功

4.2 logcat

  1. logcat -b radio // ril log
  2. logcat -c -b radio // 清除之前的log

5 参考文档

移远官方:

Quectel_UMTS_LTE_5G_Linux_USB_Driver_User_Guide_V3.0

Android RILDriver User Guide

RK官方:

Rockchip_RM310_4G模块配置说明

Rockchip_Introduction_3G_Dongle_Configuration_CN&EN

他人博客:

RK3568-ANDROID11-4G-EC20-(详细步骤)_旋风旋风的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/275214
推荐阅读
相关标签
  

闽ICP备14008679号