导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. awwwwa
    3. 最佳
    A
    • 资料
    • 关注 0
    • 粉丝 18
    • 我的积分 13500
    • 主题 11
    • 帖子 531
    • 最佳 137
    • 群组 1

    awwwwa 发布的最佳帖子

    • 回复: 【水经验混下载权限专用贴】如何升级LV2拉取SDK

      @willok 发表一个回复就是LV2了

      发布在 灌水区
      A
      awwwwa
    • 回复: 【水经验混下载权限专用贴】如何升级LV2拉取SDK

      @luminous 90783e9f-bbc3-435c-ad83-525713f6c1dc-image.png

      发布在 灌水区
      A
      awwwwa
    • 回复: 【水经验混下载权限专用贴】如何升级LV2拉取SDK

      @yinjc 85104215-d1c8-400e-a365-735a28c41fbb-image.png

      发布在 灌水区
      A
      awwwwa
    • 回复: 新 SDK 平台下载 D1-H/D1s SDK

      @zhouyuan369 删除文件夹内的.repo隐藏文件夹重新拉取

      发布在 MR Series
      A
      awwwwa
    • 回复: 新 SDK 平台下载 D1-H/D1s SDK

      @zhouyuan369 网盘要怎么接收后续更新呢,重新下载25G的压缩包吗?

      发布在 MR Series
      A
      awwwwa
    • 回复: 全志在线开源芯片 新 SDK 平台下载方法汇总

      @vaagolevs 目前R128 1.0 SDK还未正式发布,测试版SDK可能未来会有较大接口变动。请耐心等待

      发布在 代码下载问题专区
      A
      awwwwa
    • R128-S2 驱动 1024x600 RGB 显示屏 并运行 LVGL

      由于屏幕较大首先精简系统内存,关闭DSP核心,并将 RV 核心移到 HSPSRAM 上提高带宽。配置 LV_COLOR_DEPTH 16 提高帧率降低内存占用

      patch 如下,增加了新方案r128-devkit-rgb:161ca91b-f759-4108-8bfc-85114394da0c-r128-devkit-rgb.tar.gz

      编译打包即可

      700ms启动 LVGL:

      发布在 A Series
      A
      awwwwa
    • 回复: 全志在线开源芯片 新 SDK 平台下载方法汇总

      @vaagolevs 请联系销售人员获取SDK与后续的更新通知

      发布在 代码下载问题专区
      A
      awwwwa
    • 回复: 全志在线开源芯片 新 SDK 平台下载方法汇总

      @huang825172 可能目前网络不太好,稍等一下再拉取就行

      发布在 代码下载问题专区
      A
      awwwwa
    • 回复: 搭建开发环境,出现问了了,总是报fatal: cannot obtain manifest https://sdk.aw-ol.com/git_repo/V853Tina_Open/manifest.git
      1. 执行命令设置全局保存密码
      git config --global credential.helper store
      
      1. 执行命令输入密码
      git clone https://sdk.aw-ol.com/git_repo/V853Tina_Open/manifest.git
      
      1. 使用repo拉取sdk
      repo init -u https://sdk.aw-ol.com/git_repo/V853Tina_Open/manifest.git -b master -m tina-v853-open.xml
      

      由于repo更新,目前不支持通过repo输入密码,请先使用git命令输入保存密码

      发布在 V Series
      A
      awwwwa
    • 回复: V853 的 CPU1(E907)启动流程

      参考Linux端代码即可,本质上为:

      1. 加载固件
        1. 调用 firmware 接口获取文件系统中的固件
        2. 解析固件的 resource_table 段,该段有如下内容
          1. 声明需要的内存(Linux 为其分配)
          2. 声明使用的 vdev(固定为一个)
          3. 声明使用的 vring(固定为两个)
        3. 将固件加载到指定地址
      2. 注册 rpmsg virtio 设备
        1. 提供 vdev->ops(基于 virtio 接口实现的)
        2. 与 rpmsg_bus 驱动匹配,完成 rpmsg 初始化
      3. 启动小核
        1. 调用 rproc->ops->start
      发布在 RTOS
      A
      awwwwa
    • 把 D1-H T113 的 LVGL 8.1.0 升级到 8.3.2 并适配 G2D 加速

      打入以下补丁即可

      cd package
      git apply *.patch
      

      lvgl8-update-version-from-8.1.0-to-8.3.2.zip

      发布在 MR Series
      A
      awwwwa
    • 回复: 全志在线开源芯片 新 SDK 平台下载方法汇总

      @spade8

      检查下你的repo安装是不是正常的

      d13de3d0-af6e-415f-9a2f-62e74c463ad3-image.png

      发布在 代码下载问题专区
      A
      awwwwa
    • 回复: 如何申请下载Tina SDK权限?

      AWOL 支持这些芯片,提供SDK下载

      508a68b1-39ed-43e3-93ae-979221e8f2ab-image.png

      参考 https://www.aw-ol.com/docs 中的文档下载

      其他芯片需要联系你购买商家的客服或者代理获取

      发布在 Linux
      A
      awwwwa
    • 回复: Ubuntu中获取sdk

      https://blog.csdn.net/u010117864/article/details/88805136

      发布在 MR Series
      A
      awwwwa
    • 回复: 弱弱的问一句,T527是正式量产了吗?

      @hqembed 有Tina Linux AIoT,支持Buildroot,Debian

      发布在 T Series
      A
      awwwwa
    • 回复: 需要全志在线开发者论坛LV2等级以上用户才有权限拉取 SDK

      @quincy e2c5b2ed-64a3-472e-aef4-0b85617eb437-image.png

      发布在 Wireless & Analog Series
      A
      awwwwa
    • 回复: 寻求tina的display 官方文档说明,感谢
      disp init configuration
      
      disp_mode             (0:screen0<screen0,fb0>)
      screenx_output_type   (0:none; 1:lcd; 2:tv; 3:hdmi;5:vdpo)
      screenx_output_mode   (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50)
                            (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60)
      screenx_output_format (for hdmi, 0:RGB 1:yuv444 2:yuv422 3:yuv420)
      screenx_output_bits   (for hdmi, 0:8bit 1:10bit 2:12bit 2:16bit)
      screenx_output_eotf   (for hdmi, 0:reserve 4:SDR 16:HDR10 18:HLG)
      screenx_output_cs     (for hdmi, 0:undefined  257:BT709 260:BT601  263:BT2020)
      screenx_output_dvi_hdmi (for hdmi, 0:undefined 1:dvi mode 2:hdmi mode)
      screen0_output_range   (for hdmi, 0:default 1:full 2:limited)
      screen0_output_scan    (for hdmi, 0:no data 1:overscan 2:underscan)
      screen0_output_aspect_ratio  (for hdmi, 8-same as original picture 9-4:3 10-16:9 11-14:9)
      fbx format            (4:RGB655 5:RGB565 6:RGB556 7:ARGB1555 8:RGBA5551 9:RGB888 10:ARGB8888 12:ARGB4444)
      fbx pixel sequence    (0:ARGB 1:BGRA 2:ABGR 3:RGBA)
      fb0_scaler_mode_enable(scaler mode enable, used FE)
      fbx_width,fbx_height  (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0)
      lcdx_backlight        (lcd init backlight,the range:[0,256],default:197
      lcdx_yy               (lcd init screen bright/contrast/saturation/hue, value:0~100, default:50/50/57/50)
      lcd0_contrast         (LCD contrast, 0~100)
      lcd0_saturation       (LCD saturation, 0~100)
      lcd0_hue              (LCD hue, 0~100)
      framebuffer software rotation setting:
      disp_rotation_used:   (0:disable; 1:enable,you must set fbX_width to lcd_y,
      set fbX_height to lcd_x)
      degreeX:              (X:screen index; 0:0 degree; 1:90 degree; 3:270 degree)
      degreeX_Y:            (X:screen index; Y:layer index 0~15; 0:0 degree; 1:90 degree; 3:270 degree)
      devX_output_type : config output type in bootGUI framework in UBOOT-2018.
      				   (0:none; 1:lcd; 2:tv; 4:hdmi;)
      devX_output_mode : config output resolution(see include/video/sunxi_display2.h) of bootGUI framework in UBOOT-2018
      devX_screen_id   : config display index of bootGUI framework in UBOOT-2018
      devX_do_hpd      : whether do hpd detectation or not in UBOOT-2018
      chn_cfg_mode     : Hardware DE channel allocation config. 0:single display with 6
      				   channel, 1:dual display with 4 channel in main display and 2 channel in second
                         display, 2:dual display with 3 channel in main display and 3 channel in second
                         in display.
      
      发布在 V Series
      A
      awwwwa
    • 回复: 个人开发者如何获取D1、D1s的 SDK?需要签NDA吗?

      @damiaa 现在是新版本平台了,直接拿awol账号下载,免去再注册一个平台的麻烦:https://d1.docs.aw-ol.com/study/study_3getsdktoc/

      发布在 代码下载问题专区
      A
      awwwwa
    • 回复: t527 板子一开机网口灯就亮

      看硬件设计,Avaota系列板子设计网卡常量,Active时灭,BPI 设计网卡灯常灭,Avtive时亮

      发布在 T Series
      A
      awwwwa
    • 回复: DragonFace 最新版本:V4.1.5 哪里可以下载

      可以在APST下载

      发布在 爱搞机专区
      A
      awwwwa
    • 回复: uhttpd服务启动报错

      uhttpd 需要加载luci,需要勾选luci的相关配置feed。具体可以参考openwrt官方文档

      发布在 V Series
      A
      awwwwa
    • 回复: 全志在线开源芯片 新 SDK 平台下载方法汇总

      @zhongwenhua 可以

      发布在 代码下载问题专区
      A
      awwwwa
    • 回复: 【T113-I】 请问该产品支持spi传输32bit数据吗

      @wayneyao IP版本不同,驱动有修改,以手册为准,控制器支持32bit,请提供设备树和驱动修改

      发布在 T Series
      A
      awwwwa
    • 回复: V851S tina linux ov5647 驱动程序没有 dmesg

      ov5647 这个型号的摄像头并没有适配,SDK也没有支持。

      请参考V85x的摄像头支持手册选择适配的摄像头。这里推荐已经量产的产品使用的GC2063,GC2083,GC4663这三款摄像头,已经经过严格的测试与调试,可以达到最佳画质和分辨率

      https://bbs.aw-ol.com/assets/uploads/files/1661647266904-a0795b5c-bac6-4a32-8987-c214b30a0b91-allwinner-v853-raw-sensor-support-list_v1.0.pdf

      发布在 V Series
      A
      awwwwa
    • 回复: sunxi-fel对T113-S4 适配问题

      DDR驱动不兼容,参考xfel改动

      发布在 T Series
      A
      awwwwa
    • 回复: V851s使用spi nand启动不了 VFS: Cannot open root device "ubi0_4" or unknown-block(0,0): error -2

      @dnvwf

      重点:rootfstype=squashfs

      v851s/configs/xxx/env.cfg

      
      #kernel command arguments
      earlyprintk=sunxi-uart,0x02500000
      initcall_debug=0
      console=ttyS0,115200
      nand_root=/dev/ubiblock0_4
      mmc_root=/dev/mmcblk0p4
      nor_root=/dev/mtdblock3
      init=/init
      rdinit=/rdinit
      loglevel=8
      coherent_pool=32K
      #reserve_list=30M@64M,78M@128M,200M@512M
      mac=
      wifi_mac=
      bt_mac=
      specialstr=
      root_partition=rootfs
      mtd_name=sys
      rootfstype=squashfs
      #set kernel cmdline if boot.img or recovery.img has no cmdline we will use this
      setargs_nor=setenv bootargs  earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nor_root} rootwait init=${init} rdinit=${rdinit} partitions=${partitions} cma=${cma} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      setargs_nand=setenv bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel}  ubi.mtd=${mtd_name} root=${nand_root} rootfstype=${rootfstype} rootwait init=${init} rdinit=${rdinit} partitions=${partitions} cma=${cma} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      setargs_nand_ubi=setenv bootargs ubi.mtd=${mtd_name} ubi.block=0,${root_partition} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
      setargs_mmc=setenv  bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${mmc_root}  rootwait init=${init} partitions=${partitions} cma=${cma} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      #nand command syntax: sunxi_flash read address partition_name read_bytes
      #0x4007f800 = 0x40080000(kernel entry) - 0x800(boot.img header 2k)
      boot_partition=boot
      boot_normal=sunxi_flash read 44800000 ${boot_partition};bootm 44800000
      boot_recovery=sunxi_flash read 44800000 extend;bootm 44800000
      boot_fastboot=fastboot
      #recovery key
      recovery_key_value_max=0x13
      recovery_key_value_min=0x10
      #fastboot key
      fastboot_key_value_max=0x8
      fastboot_key_value_min=0x2
      
      #uboot system env config
      bootdelay=1
      #default bootcmd, will change at runtime according to key press
      #default nand boot
      bootcmd=run setargs_nand boot_normal
      #verify the kernel
      verify=N
      
      发布在 V Series
      A
      awwwwa
    • 回复: 有R128点亮百问网7寸RGB屏的DEMO吗?

      R128-S2 驱动 1024x600 RGB 显示屏 并运行 LVGL
      https://bbs.aw-ol.com/topic/4316/share/1

      发布在 A Series
      A
      awwwwa
    • 回复: D1-H芯片用户手册中文版

      7b555183-66d6-497d-97d8-2b6a7ee4f7dd-image.png

      发布在 MR Series
      A
      awwwwa
    • 回复: 关于Linux环境下R128的烧录环境

      @cai_yp openSUSE 需要装虚拟机使用

      发布在 A Series
      A
      awwwwa
    • 回复: 请问D1s支持有源晶振吗?

      支持,HXIN接有源,HXOUT接地

      发布在 MR Series
      A
      awwwwa
    • 回复: V851s buildroot openwrt 警告

      @kanken6174 在 V851s buildroot openwrt 警告 中说:

      忽略这些警告

      忽略这些警告即可,这些是openwrt提供的软件包,暂时不适配v851s平台,所以有警告

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: D1-H的HiFi4 DSP是否有库可以用

      https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP

      发布在 MR Series
      A
      awwwwa
    • 回复: A133 AW869A WIFI模块问题 死循环报RTO

      没有看到相关log

      发布在 Linux
      A
      awwwwa
    • 回复: R128 打包失败 merge_full_rtos_img_failed

      @cai_yp 分区参数错误,只打包了UDISK分区,但是UDISK是自动生成的分区

      32356+0 records in
      32356+0 records out
      8283136 bytes (8.3 MB) copied, 0.0394041 s, 210 MB/s
      this is not a partition key
      update mbr file ok
      ----------------mbr convert to gpt start---------------------
      out: sunxi_gpt_nor.fex
      source: sunxi_mbr_nor.fex
      input_logic_offset: 256
      input_flash_size: 16M
      gpt partition entry crc32 = 0x618ebc8
      gpt header crc32 = 0x4fdf09e2
      GPT----part num 10---
      gpt_entry: 128
      gpt_header: 92
      GPT:env         : 120           127
      GPT:env-redund  : 128           12f
      GPT:arm-lpsram  : 130           a8f
      GPT:rv-lpsram   : a90           1a2f
      GPT:dsp-hpsram  : 1a30          206f
      GPT:rtos-xip    : 2070          33f7
      GPT:arm-b       : 33f8          3d57
      GPT:config      : 3d58          3d77
      GPT:settings    : 3d78          3db7
      GPT:UDISK       : 3db8          7fff
      update gpt file ok
      ----------------mbr convert to gpt end---------------------
      boot0: boot0_spinor.fex
      redund boot0: boot0_spinor.fex
      mbr: sunxi_gpt_nor.fex
      partition: sys_partition_nor.bin
      UDISK_partition_size: 16968 sector
      outfile: rtos_16Mnor.bin
      logic_start: 128K
      total_image_size: 16M
      load file: boot0_spinor.fex ok
      load file: sunxi_gpt_nor.fex ok
      load file: boot0_spinor.fex ok
      support redund boot0 at 0x10000
      load file: sys_partition_nor.bin ok
      part name=env
      file name:env.fex
      part size:8 sector
      load file: env.fex ok
      part name=env-redund
      file name:env.fex
      part size:8 sector
      load file: env.fex ok
      part name=arm-lpsram
      file name:rtos_arm.fex
      part size:2400 sector
      load file: rtos_arm.fex ok
      part name=rv-lpsram
      file name:rtos_riscv.fex
      part size:4000 sector
      load file: rtos_riscv.fex ok
      part name=dsp-hpsram
      file name:rtos_dsp.fex
      part size:1600 sector
      load file: rtos_dsp.fex ok
      part name=rtos-xip
      file name:rtos_xip_rv.fex
      part size:5000 sector
      load file: rtos_xip_rv.fex ok
      part name=arm-b
      file name:etf.fex
      part size:2400 sector
      load file: etf.fex ok
      part name=config
      file name:config.fex
      part size:32 sector
      load file: config.fex ok
      part name=settings
      part size:64 sector
      part name=UDISK
      file name:data_udisk.fex
      load file: data_udisk.fex ok
      partname: UDISK
      this is not a partition key
      merge_package ok
      
      
      发布在 MR Series
      A
      awwwwa
    • 回复: GT911 触摸滑动不流畅

      可以尝试中断绑定其他CPU核心,例如CPU1

      发布在 Linux
      A
      awwwwa
    • 回复: MR536 SDK MR536_V1.1直接编译和打包后烧录全志MR536 evk(黄色),报错如下: Unable to handle kernel paging request at virtual address 0000000000040008

      Unable to handle kernel paging request at virtual address 0000000000040008

      看看内核代码rb_next附近,有非法地址访问

      发布在 MR Series
      A
      awwwwa
    • 给 Gaviar Handheld (小志掌机) 适配了一个固件,魂斗罗游戏机

      先上固件:

      9724ff03-b4bc-4a07-8bac-05431383d983-gaviarhandhelda.img

      发布在 爱搞机专区
      A
      awwwwa
    • 回复: 新 SDK 平台下载 XR806 SDK

      @woxow 把你的proxy代理关了

      发布在 Wireless & Analog Series
      A
      awwwwa
    • 回复: 有没有大佬知道这个f1c100s和stm32去通信,配置好烧到板子上串口走不下去了

      Linux都没启动,先检查为什么Linux没启动

      发布在 Linux
      A
      awwwwa
    • 回复: adb找不到设备

      目前板子处于烧录下载模式,显示 USB Device (VID_xxxx_PID_xxxx),需要进入系统后才是adb模式,显示 Tina ADB

      发布在 MR Series
      A
      awwwwa
    • 回复: 請問大大誰有usb驅動程式能下載?

      @abc16883
      下载工具:
      AllwinnertechPhoeniSuitRelease20230905.zip

      下载驱动:
      全志USB烧录驱动20201229

      发布在 爱搞机专区
      A
      awwwwa
    • 回复: 新 SDK 平台下载 XR806 SDK

      @zhoudaxia3000 目前最新的是1.2.2

      发布在 Wireless & Analog Series
      A
      awwwwa
    • 回复: UDSIK分区表的大小和实际系统挂载的大小不对应

      UDISK属性写错了

      发布在 Linux
      A
      awwwwa
    • Tina Linux 使用 adb dump、修改设备的 rootfs

      adb 可用时可以直接读取 /dev/by-name/rootfs 将rootfs导出来

      adb pull /dev/by-name/rootfs rootfs.img
      

      也可以push到tmp文件夹然后dd写入

      adb push rootfs.img /tmp
      dd if=/tmp/rootfs.img of=/dev/by-name/rootfs
      
      发布在 MR Series
      A
      awwwwa
    • 回复: 烧录suit工具写flash卡在7%

      @missdangerous 固件损坏,GUID 分区表损坏

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: XR829的LPCLK

      只要LPCLK引脚接地,就可以使用内部RC时钟32K,这个时钟不准确。如果不需要使用低功耗可以不外挂

      发布在 Wireless & Analog Series
      A
      awwwwa
    • 回复: 关于PhoenixCardv4.2.7

      377391af-878f-4a41-b29a-7c50b6faad29-image.png

      NOR固件不能烧卡

      发布在 Linux
      A
      awwwwa
    • 回复: 请教拉取sdk问题

      @huangyuhan 没有配置默认保存用户名密码,需要多次输入

      发布在 MR Series
      A
      awwwwa
    • 回复: V851s buildroot openwrt 编译GCC失败

      @kanken6174 不建议编译gcc进入固件,首先这个gcc没有适配平台,其次v851s的64M内存也无法支持gcc的使用

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: XR806 SDK不能下载

      xr806 使用 git clone,不是repo

      https://xr806.docs.aw-ol.com/rtos/env/

      61923b6b-f856-4b78-ae9d-54ae877090af-image.png

      发布在 Wireless & Analog Series
      A
      awwwwa
    • busybox init 简介

      一、简介

      tina 使用busybox init方式启动,首先调用执行pseudo_init(挂载文件系统,如/proc、/tmp、/sys /etc、/usr),接着会调用/sbin/init进程,而init进程调用的第一个启动脚本为/etc/init.d/rcS。


      二、平台的自定义
      不同的平台文件系统具有其共性与特殊性。tina/packge/busybox-init-base-files/files下提供了所有平台的基础文件。而在tina/target/allwinner/XXX/busybox-init-base-files下存放的是平台特性文件,其优先级高于前者,即当前者目录和后者存在有相同文件时,以后者为准。如有以下两个文件:

      A:tina/target/allwinner/r11-R11_pref1/busybox-init-base-files/etc/banner
      B:tina/package/busybox-init-base-files/files/etc/banner

      最终拷贝到文件系统中的为A。


      三、pseudo_init与rcS
      pseudo_init与rcS文件中存在很多平台共性的代码,避免系统充斥大量冗余代码,以及方便基础文件的维护和开发。所以不允许在特定平台下自定义pseudo_init、rcS文件(必须使用tina/packge/busybox-init-base-files/files下的pseudo_init、rcS)。
      如果需要添加平台特定配置(pseudo_init,rcS没有配置),可将其写到rc.preboot,rc.final中,参考第四节。


      四、rcS脚本
      1.功能描述
      (1)执行/etc/init.d/rc.preboot。
      为了满足开机快速启动的需求,提供了用户可自定义rc.preboot文件,即在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/目录下创建rc.preboot脚本文件,将会被rcS最先调用执行。
      (2)配置打印级别,主机名称。
      (3)执行/etc/init.d/rc.log,配置系统log信息。
      系统默认使用的是tina/package/busybox-init-base-files/files/etc/init.d/rc.log脚本进行配置系统log信息。用户可在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下创建rc.log,自定义rc.log。
      如果需要使用默认rc.log,需要在make menuconfig配置。

      	Base system  --->
      	 busybox-init-base-files......................... Busybox init base system  --->
      	  [*]   Use the rc.log
      

      (4)挂载UDISK。
      (5)执行/etc/init.d/rc.modules,加载内核模块。
      系统默认使用的是tina/package/busybox-init-base-files/files/etc/init.d/rc.modules脚本进行内核模块自加载,用户可在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下创建rc.modules,自定义rc.modules。
      如果需要使用默认rc.modules,需要在make menuconfig配置如下。

      	Base system  --->
      	 busybox-init-base-files......................... Busybox init base system  --->
      	   [*]   Use the rc.modules
      

      (6)启动/etc/rc.d下的脚本。

      关于执行rc.d下的启动脚本,目的为兼容procd式的应用脚本。/etc/rc.d下的脚本是链接到/etc/init.d/下,默认情况下只执行adbd,如果需要执行其他脚本,需要在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下,自定义load_script.conf文件,文件内容中写上要启动的应用,如adbd(注意,每一个应用占一行)。可参考:tina/packge/busybox-init-base-files/files/etc/init.d/load_script.conf。
      
      	如果需要执行rc.d下的启动脚本,需要在make menuconfig做如下配置。
      	Base system  --->
      	 busybox-init-base-files......................... Busybox init base system  --->
      	   [*]   Auto load the script in /etc/rc.d
      

      (7)ota初始化。

      (8)执行/etc/init.d/rc.final,用户自定义启动脚本。
      用户可在tina/packge/busybox-init-base-files/files/etc/init.d/下创建一个rc.final脚本,自定义启动应用程序,该脚本将会被rcS最后调用执行。

      2.rc.preboot与rc.final的区别?
      rc.preboot比rc.final先运行,在执行rc.preboot脚本的时候,系统的一些初始化操作还没完成,如挂载UDISK、内核模块自加载、ota等等操作。而rc.final执行的时候,以上的初始化操作已经完成。

      五.如何写应用的启动脚本

      example:开机自启动smartlinkd(tina/package/allwinner/smartlinkd/files/smartlinkd.init)
      1.方法一(特定格式要求)

      详细的格式参考:
      https://wiki.openwrt.org/inbox/procd-init-scripts
      https://wiki.openwrt.org/doc/techref/initscripts

      (1)procd式

      #!/bin/sh /etc/rc.common   #本质为script脚本,以#!开头, 之后执行/etc/rc.common
      START=98		#开机启动优先级(序列) [数值越小, 越先启动]
      STOP=98			#关机停止优先级(序列) [数值越小, 越先关闭]
      
      USE_PROCD=1
      PROG=smartlinkd
      
      start_service() {    #启动函数
          procd_open_instance
          procd_set_param command $PROG -d
          procd_close_instance
      }
      
      shutdown() {
          echo shutdown
      }
      

      (2)Sys式

      #!/bin/sh /etc/rc.common
      START=98
      STOP=98
      
      PROG=smartlinkd
      
      start() {
        smartlinkd -d &
      }
      
      

      使用上述procd式和sys式脚本,既能兼容procd init启动和busybox init的启动方式。
      另外如果使用的是busybox init的启动方式,还需要在load_script.conf文件中换行添加内容:smartlinkd

      2.方法二(无特定格式要求)
      创建rc.preboot或者rc.final脚本,添加启动smartlinkd的内容。

      发布在 Linux
      A
      awwwwa
    • 回复: 为什么添加Gstreamer后会报这个错误

      没有交叉编译,gstreamer没有配置交叉编译工具

      发布在 MR Series
      A
      awwwwa
    • 回复: 烧录识别不了usb提示:module awusb:gnu.linkonce.this module section size must match the kernel's built struct module size at run time

      内核版本不匹配,请更换Ubuntu内核版本到5.15.y,目前你是6.5

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: 如何将Libuvc编译到tina系统中

      参照opencv的编写使用cmake的makefile

      include $(TOPDIR)/rules.mk
      
      PKG_NAME:=opencv
      PKG_VERSION:=4.1.1
      PKG_RELEASE:=1
      
      PKG_SOURCE_PROTO:=git
      PKG_SOURCE_URL:=https://github.com/opencv/opencv
      PKG_SOURCE_VERSION:=$(PKG_VERSION)
      PKG_MIRROR_HASH:=c8587820421d2f22acdafe4712d068ae490897dc445bdb4aa128ecaa8e65d3a1
      
      PKG_MAINTAINER:=
      PKG_LICENSE:=BSD-3-Clause
      PKG_LICENSE_FILES:=LICENSE
      
      CMAKE_INSTALL:=1
      CMAKE_BINARY_SUBDIR:=build
      PKG_BUILD_PARALLEL:=1
      PKG_USE_MIPS16:=0
      
      include $(INCLUDE_DIR)/package.mk
      include $(INCLUDE_DIR)/cmake.mk
      
      define Package/opencv/Default/description
       OpenCV (Open Source Computer Vision Library) is an open source computer
       vision and machine learning software library. OpenCV was built to provide
       a common infrastructure for computer vision applications and to accelerate
       the use of machine perception in the commercial products. Being a
       BSD-licensed product, OpenCV makes it easy for businesses to utilize
       and modify the code.
      endef
      
      define Package/opencv
        SECTION:=libs
        CATEGORY:=Libraries
        TITLE:=OpenCV
        URL:=https://opencv.org/
        DEPENDS:=+libpthread +librt +libatomic +libstdcpp +zlib +libjpeg +python3 +python3-numpy
      endef
      
      CMAKE_OPTIONS += \
      	-DBUILD_opencv_gpu:BOOL=OFF \
      	-DWITH_1394:BOOL=OFF -DBUILD_opencv_stitching:BOOL=OFF \
      	-DBUILD_opencv_superres:BOOL=OFF -DBUILD_opencv_ts:BOOL=OFF \
      	-DBUILD_opencv_highgui:BOOL=ON \
      	-DBUILD_opencv_videostab:BOOL=OFF \
      	-DWITH_FFMPEG:BOOL=OFF \
      	-DWITH_GSTREAMER:BOOL=OFF \
      	-DWITH_LIBV4L:BOOL=ON \
      	-DWITH_PNG:BOOL=OFF \
      	-DWITH_GTK:BOOL=OFF \
      	-DWITH_TIFF:BOOL=OFF \
      	-DCMAKE_VERBOSE:BOOL=OFF \
      	-DENABLE_PRECOMPILED_HEADERS=OFF \
      	-DPYTHON3_INCLUDE_PATH=$(STAGING_DIR)/usr/include/python3.9 \
      	-DPYTHON3_LIBRARIES=$(STAGING_DIR)/usr/lib/libpython3.9.so \
      	-DPYTHON3_NUMPY_INCLUDE_DIRS=$(TARGET_ROOTFS_DIR)/pypi/numpy-1.20.1/ipkg-install/usr/lib/python3.9/site-packages/numpy/core/include \
      	-DBUILD_OPENCV_PYTHON3:BOOL=ON
      
      TARGET_LDFLAGS += -latomic
      
      define Package/opencv/install
      	$(INSTALL_DIR) $(1)/usr/lib
      	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
      endef
      
      $(eval $(call BuildPackage,opencv))
      
      发布在 V Series
      A
      awwwwa
    • T113 busybox init 配置 overlayfs 为 UDISK 分区而不是 rootfs_data
      1. 先确定挂载overlayfs

      查看 pseudo_init 中 MOUNT_OVERLAY 是不是 1,如果不是配置为 1

      package/busybox-init-base-files/files/pseudo_init
      

      9a131c14-2a2c-493d-8acc-b623cce5a138-image.png

      1. 修改挂载分区

      找到文件末尾,吧 rootfs_data 改成UDISK

      c3474e4a-e208-4549-9a82-9d9cc7372300-image.png

      发布在 Linux
      A
      awwwwa
    • 回复: 为什么添加Gstreamer后会报这个错误

      @uccccc 在 为什么添加Gstreamer后会报这个错误 中说:

      @awwwwa 麻烦问一下这个应该怎麼添加,有没有相关的资料亚

      https://openwrt.org/docs/guide-developer/packages

      发布在 MR Series
      A
      awwwwa
    • 回复: 求教PhoenixSuit无设备连接问题

      参考这里,重新安装下驱动
      https://r128.docs.aw-ol.com/r128/prepare_dev_env/#windows_1

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: camerademo.c修改后编译打包的camerademo不变

      mmo camerademo -B

      发布在 V Series
      A
      awwwwa
    • 回复: t113使用sd卡启动卡住了

      @xingxing8 在 t113使用sd卡启动卡住了 中说:

      先看这行

      VFS: Cannot open root device "mmcblk0p5" or unknown-block(0,0): error -6

      这行表示没有挂载上mmc设备

      再往上找

      [ 4.002919] sunxi-mmc 4020000.sdmmc: Got CD GPIO
      [ 4.008458] sunxi-mmc 4020000.sdmmc: set cd-gpios as 24M fail
      [ 4.018859] sunxi-mmc 4020000.sdmmc: sdc set ios:clk 0Hz bm PP pm UP vdd 21 width 1 timing LEGACY(SDR12) dt B

      CD卡检测GPIO检测不到卡,关闭MMC驱动

      Linux中的驱动为了省电会根据CD引脚检测卡是否存在,不存在则关闭MMC驱动,U-boot驱动没有这个逻辑

      解决方法:

      1. 正向解决法
      • 根据实物硬件查看CD引脚配置,上下拉状态是否正常,是否反转CD
        83a89a3e-cad1-4bd7-9ad4-7d8caa3f582f-image.png
      1. 软件规避法
      • 直接关闭CD检测功能,取消注释 broken-cd;
        8fb933a9-17ad-4ed8-b25a-ac7d1e157945-image.png
      发布在 Linux
      A
      awwwwa
    • 回复: T113 nand flash 启动失败

      @cwj1986521 内核没有配置UBIFS

      5140d1f6-ea76-42f0-b4fd-9fac6c725ebb-image.png

      83e11990-9d61-49d0-9eac-ac1d699cb2cb-image.png

      CONFIG_UBIFS_FS=y
      CONFIG_UBIFS_FS_ADVANCED_COMPR=y
      # CONFIG_UBIFS_FS_LZO is not set
      # CONFIG_UBIFS_FS_ZLIB is not set
      # CONFIG_UBIFS_FS_ZSTD is not set
      # CONFIG_UBIFS_ATIME_SUPPORT is not set
      CONFIG_UBIFS_FS_XATTR=y
      CONFIG_UBIFS_FS_SECURITY=y
      
      发布在 MR Series
      A
      awwwwa
    • 回复: OpenixCard - 在 Linux 系统刷写全志镜像到 SD 卡

      @yunyisa 自制的固件无法打包成全志的镜像,只能由SDK生成,全志镜像有专有的封装格式,不仅仅是地址偏移

      发布在 编译和烧写问题专区
      A
      awwwwa
    • 回复: V853 DDR原理图问题

      AW平台的DRAM控制器支持地址线REMAP,可以通过REMAP简化外部不同种类的DRAM的连接。

      这个REAMP是固定在芯片里的不能自己修改,在电路原理图可以看到REMAP的引脚。

      如图,如果需要挂DDR3内存,需要接DDR3的REAMP,如果需要接DDR2,可以接默认的REMAP

      07d2327d-bde1-4367-97e2-5b4b770b35e7-image.png

      举个其他平台的例子:
      这里接的是 LPDDR4,使用LPDDR4的REMAP
      84281c99-eb73-4892-b50d-bf3132389541-image.png

      这里接的是DDR4,使用DDR4的REMAP
      b14dfa2e-9a5f-4ba1-98bb-8f7d8541fc3b-image.png

      发布在 V Series
      A
      awwwwa
    • 回复: A133驱动 st7701s[480x480]问题

      uboot的设备树和kernel的设备树都需要配置

      发布在 Linux
      A
      awwwwa
    • 回复: T113 nand flash 启动失败

      @cwj1986521 需要用 make kernel_menuconfig,如果使用的是build.sh 需要 ./build.sh menuconfig

      内核配置文件会被SDK覆盖,进入内核文件夹修改的均无效

      发布在 MR Series
      A
      awwwwa
    • 回复: DshanMCU-R128s2-EVT 最全最强最丰富的企业评估套件来啦!!!
      • 测试固件
        rtos_freertos_r128s2_evt_uart0_16Mnor.img
      发布在 A Series
      A
      awwwwa
    • 回复: V851S SPI2 死机

      对照手册:

      • SPI2 地址 0x04027000, 没问题
        0f2f1b97-2298-4112-923a-c25db5428943-image.png

      • SPI2 中断号 49,配置时需要减掉SIG和PPI的数量32,也就是17
        eeb6838d-b14f-441f-870b-badb6672796a-lQLPJxe-6SonLpDM2s0B87B4X1hs1FJTtAUq12ehL88A_499_218.png

      中断号配置错误,应该为17不是18

      		spi2: spi@04027000 {
      			#address-cells = <1>;
      			#size-cells = <0>;
      			compatible = "allwinner,sun8i-spi";
      			device_type = "spi2";
      			reg = <0x0 0x04027000 0x0 0x1000>;
      			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
      			clocks = <&clk_pll_periph0300m>, <&clk_spi2>;
      			status = "disabled";
      		};
      
      发布在 V Series
      A
      awwwwa
    • 回复: 请教如何排查 linux kernel 启动卡主的问题

      @xsyr1024 在 请教如何排查 linux kernel 启动卡主的问题 中说:

      [ 0.969253] 000: printk: console [ttyS0] enabled
      [ 0.973945] 000: printk: bootconsole [earlycon0] disabled

      看着是earlycon0作为串口输出驱动正常,但是切换到ttyS0作为串口输出的时候ttyS0没有输出,先检查uart部分

      另外这个是LinuxRT内核吗

      发布在 Linux
      A
      awwwwa
    • 回复: d1s 原理图请求指导问题

      此处的电容不可以省略

      dd52baa4-1ff8-472f-96ae-a9a51efdcbfb-image.png

      AVCC,VRAx 需要外挂电容

      发布在 MR Series
      A
      awwwwa
    • 回复: R128-S2 驱动 1024x600 RGB 显示屏 并运行 LVGL

      屏参改一下

      lcd_driver_name     = "default_lcd"
      lcd_backlight       = 150
      lcd_if              = 0
      lcd_x               = 1024
      lcd_y               = 600
      lcd_width           = 150
      lcd_height          = 94
      lcd_rb_swap         = 0
      lcd_dclk_freq       = 48
      lcd_pwm_used        = 1
      lcd_pwm_ch          = 7
      lcd_pwm_freq        = 500000
      lcd_pwm_pol         = 1
      lcd_hbp             = 160
      lcd_ht              = 1344
      lcd_hspw            = 20
      lcd_vbp             = 20
      lcd_vt              = 635
      lcd_vspw            = 3
      lcd_lvds_if         = 0
      lcd_lvds_colordepth = 1
      lcd_lvds_mode       = 0
      lcd_frm             = 0
      lcd_io_phase        = 0x0000
      lcd_gamma_en        = 0
      lcd_bright_curve_en = 0
      lcd_cmap_en         = 0
      
      发布在 A Series
      A
      awwwwa
    • 回复: V853使用MIPI CSI接口是否只支持RAW格式像素?

      @xjy_5 一般来说配置sensor0_isp_used = <0>; 就不会调用ISP,虽然会配置但是不会处理。需要再跟踪一下调用

      发布在 V Series
      A
      awwwwa
    • 回复: 全志提供的交叉编译环境头文件的问题

      @arnis

      obj-m  := hello.o
      KERNEL := ../lichee/linux-5.4/
      PWD    := $(shell pwd)
      
      modules :
              $(MAKE) -C $(KERNEL) M=$(PWD) modules
      
      .PHONEY:clean
      clean :
              rm -f *.o *.ko
      

      这是一个基本的内核模块Makefile。下面是各个变量和命令的含义:

      obj-m  := hello.o
      

      定义要编译的内核模块的目标文件名为hello.o。这里使用了obj-m变量,它是一个特殊的变量,用于编译内核模块。

      KERNEL := ../lichee/linux-5.4/
      

      定义内核源代码目录的位置,这里是../lichee/linux-5.4/。根据实际情况修改该路径。

      PWD    := $(shell pwd)
      

      定义当前目录的路径为PWD。这里使用了shell命令来获取当前目录的路径。

      modules :
              $(MAKE) -C $(KERNEL) M=$(PWD) modules
      

      定义一个名为modules的伪目标,它的依赖关系为空。执行该目标时,会进入内核源代码目录$(KERNEL),并使用M=$(PWD)选项告诉内核Makefile,模块源代码在当前目录中。最后执行modules目标,编译内核模块。

      .PHONEY:clean
      clean :
              rm -f *.o *.ko
      

      定义一个伪目标clean,它的依赖关系为空。执行该目标时,会删除当前目录下的所有.o和.ko文件。

      如果需要编译多个内核模块,可以将obj-m变量中的目标文件名替换为多个目标文件名,如obj-m := hello.o world.o another.o。此外,还可以在Makefile中定义其他命令,比如安装、卸载等命令,以更方便地管理内核模块。

      编译指令如下:

      make ARCH=arm CROSS_COMPILE=$(pwd)/../prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin/arm-openwrt-linux-gnueabi-
      

      这是一个编译ARM架构的程序的Makefile命令。下面是各个参数的含义:

      ARCH=arm
      

      指定目标架构为ARM。

      CROSS_COMPILE=$(pwd)/../prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin/arm-openwrt-linux-gnueabi-
      

      指定交叉编译器的路径及前缀。这里使用了$(pwd)变量获取当前工作目录的路径,并拼接上交叉编译器的路径及前缀。根据实际情况修改该路径。

      使用交叉编译器可以在x86主机上编译ARM平台的程序。arm-openwrt-linux-gnueabi-是交叉编译器的前缀,表示编译出来的可执行文件适用于OpenWrt系统。

      在执行该命令之前,需要确保已经安装了相应的交叉编译工具链,并将其加入环境变量中。如果没有安装,请参考相关文档进行安装。

      发布在 Linux
      A
      awwwwa
    • 回复: D1s DMA驱动Ledc 问题
      // SPDX-License-Identifier: GPL-2.0-only
      /*
       * drivers/leds/leds-sunxi.c - Allwinner RGB LED Driver
       *
       * Copyright (C) 2018 Allwinner Technology Limited. All rights reserved.
       *      http://www.allwinnertech.com
       *
       *Author : Albert Yu <yuxyun@allwinnertech.com>
       *	   Lewis <liuyu@allwinnertech.com>
       * This program is free software; you can redistribute it and/or modify
       * it under the terms of the GNU General Public License version 2 as
       * published by the Free Software Foundation.
       *
       */
      
      #include <linux/module.h>
      #include <linux/delay.h>
      #include <linux/leds.h>
      #include <linux/io.h>
      #include <linux/of.h>
      #include <linux/slab.h>
      #include <linux/clk.h>
      #include <linux/dmaengine.h>
      #include <linux/interrupt.h>
      #include <linux/platform_device.h>
      #include <linux/pinctrl/consumer.h>
      #include <linux/dma-mapping.h>
      #include <linux/debugfs.h>
      #include <linux/uaccess.h>
      #include <linux/delay.h>
      #include <linux/regulator/consumer.h>
      #include <linux/reset.h>
      
      #if IS_ENABLED(CONFIG_PM)
      #include <linux/pm.h>
      #endif
      #include "leds-sunxi.h"
      
      /* For debug */
      #define LED_ERR(fmt, arg...) pr_err("%s()%d - "fmt, __func__, __LINE__, ##arg)
      
      #define dprintk(level_mask, fmt, arg...)				\
      do {									\
      	if (unlikely(debug_mask & level_mask))				\
      		pr_warn("%s()%d - "fmt, __func__, __LINE__, ##arg);	\
      } while (0)
      
      static u32 debug_mask = 1;
      static struct sunxi_led *sunxi_led_global;
      static struct class *led_class;
      
      #define sunxi_slave_id(d, s) (((d)<<16) | (s))
      
      /*For Driver */
      static void led_dump_reg(struct sunxi_led *led, u32 offset, u32 len)
      {
      	u32 i;
      	u8 buf[64], cnt = 0;
      
      	for (i = 0; i < len; i = i + REG_INTERVAL) {
      		if (i%HEXADECIMAL == 0)
      			cnt += sprintf(buf + cnt, "0x%08x: ",
      					(u32)(led->res->start + offset + i));
      
      		cnt += sprintf(buf + cnt, "%08x ",
      				readl(led->iomem_reg_base + offset + i));
      
      		if (i%HEXADECIMAL == REG_CL) {
      			pr_warn("%s\n", buf);
      			cnt = 0;
      		}
      	}
      }
      
      static void sunxi_clk_get(struct sunxi_led *led)
      {
      	struct device *dev = led->dev;
      	struct device_node *np = dev->of_node;
      
      	led->clk_ledc = of_clk_get(np, 0);
      	if (IS_ERR(led->clk_ledc))
      		LED_ERR("failed to get clk_ledc!\n");
      
      	led->clk_cpuapb = of_clk_get(np, 1);
      	if (IS_ERR(led->clk_cpuapb))
      		LED_ERR("failed to get clk_cpuapb!\n");
      }
      
      static void sunxi_clk_put(struct sunxi_led *led)
      {
      	clk_put(led->clk_ledc);
      	clk_put(led->clk_cpuapb);
      	led->clk_ledc = NULL;
      	led->clk_cpuapb = NULL;
      }
      
      static void sunxi_clk_enable(struct sunxi_led *led)
      {
      	clk_prepare_enable(led->clk_ledc);
      	clk_prepare_enable(led->clk_cpuapb);
      }
      
      static void sunxi_clk_disable(struct sunxi_led *led)
      {
      	clk_disable_unprepare(led->clk_ledc);
      }
      
      static void sunxi_clk_init(struct sunxi_led *led)
      {
      	sunxi_clk_get(led);
      	sunxi_clk_enable(led);
      }
      
      static void sunxi_clk_deinit(struct sunxi_led *led)
      {
      	sunxi_clk_disable(led);
      	sunxi_clk_put(led);
      }
      
      static u32 sunxi_get_reg(int offset)
      {
      	struct sunxi_led *led = sunxi_led_global;
      	u32 value = ioread32(((u8 *)led->iomem_reg_base) + offset);
      
      	return value;
      }
      
      static void sunxi_set_reg(int offset, u32 value)
      {
      	struct sunxi_led *led = sunxi_led_global;
      
      	iowrite32(value, ((u8 *)led->iomem_reg_base) + offset);
      }
      
      static inline void sunxi_set_reset_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 mask = 0x1FFF;
      	u32 min = SUNXI_RESET_TIME_MIN_NS;
      	u32 max = SUNXI_RESET_TIME_MAX_NS;
      
      	if (led->reset_ns < min || led->reset_ns > max) {
      		LED_ERR("invalid parameter, reset_ns should be %u-%u!\n",
      				min, max);
      		return;
      	}
      
      	n = (led->reset_ns - 42) / 42;
      	reg_val = sunxi_get_reg(LED_RESET_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~(mask << 16);
      	reg_val |= (n << 16);
      	sunxi_set_reg(LED_RESET_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_set_t1h_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 mask = 0x3F;
      	u32 shift = 21;
      	u32 min = SUNXI_T1H_MIN_NS;
      	u32 max = SUNXI_T1H_MAX_NS;
      
      	if (led->t1h_ns < min || led->t1h_ns > max) {
      		LED_ERR("invalid parameter, t1h_ns should be %u-%u!\n",
      				min, max);
      		return;
      	}
      
      	n = (led->t1h_ns - 42) / 42;
      	reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~(mask << shift);
      	reg_val |= n << shift;
      	sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_set_t1l_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 mask = 0x1F;
      	u32 shift = 16;
      	u32 min = SUNXI_T1L_MIN_NS;
      	u32 max = SUNXI_T1L_MAX_NS;
      
      	if (led->t1l_ns < min || led->t1l_ns > max) {
      		LED_ERR("invalid parameter, t1l_ns should be %u-%u!\n",
      				min, max);
      		return;
      	}
      
      	n = (led->t1l_ns - 42) / 42;
      	reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~(mask << shift);
      	reg_val |= n << shift;
      	sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_set_t0h_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 mask = 0x1F;
      	u32 shift = 6;
      	u32 min = SUNXI_T0H_MIN_NS;
      	u32 max = SUNXI_T0H_MAX_NS;
      
      	if (led->t0h_ns < min || led->t0h_ns > max) {
      		LED_ERR("invalid parameter, t0h_ns should be %u-%u!\n",
      			min, max);
      		return;
      	}
      
      	n = (led->t0h_ns - 42) / 42;
      	reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~(mask << shift);
      	reg_val |= n << shift;
      	sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_set_t0l_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 min = SUNXI_T0L_MIN_NS;
      	u32 max = SUNXI_T0L_MAX_NS;
      
      	if (led->t0l_ns < min || led->t0l_ns > max) {
      		LED_ERR("invalid parameter, t0l_ns should be %u-%u!\n",
      				min, max);
      		return;
      	}
      
      	n = (led->t0l_ns - 42) / 42;
      	reg_val = sunxi_get_reg(LED_T01_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~0x3F;
      	reg_val |= n;
      	sunxi_set_reg(LED_T01_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_set_wait_time0_ns(struct sunxi_led *led)
      {
      	u32 n, reg_val;
      	u32 min = SUNXI_WAIT_TIME0_MIN_NS;
      	u32 max = SUNXI_WAIT_TIME0_MAX_NS;
      
      	if (led->wait_time0_ns < min || led->wait_time0_ns > max) {
      		LED_ERR("invalid parameter, wait_time0_ns should be %u-%u!\n",
      				min, max);
      		return;
      	}
      
      	n = (led->wait_time0_ns - 42) / 42;
      	reg_val = (1 << 8) | n;
      	sunxi_set_reg(LEDC_WAIT_TIME0_CTRL_REG, reg_val);
      }
      
      static inline void sunxi_set_wait_time1_ns(struct sunxi_led *led)
      {
      	unsigned long long tmp, max = SUNXI_WAIT_TIME1_MAX_NS;
      	u32 min = SUNXI_WAIT_TIME1_MIN_NS;
      	u32 n, reg_val;
      
      	if (led->wait_time1_ns < min || led->wait_time1_ns > max) {
      		LED_ERR("invalid parameter, wait_time1_ns should be %u-%llu!\n",
      			min, max);
      		return;
      	}
      
      	tmp = led->wait_time1_ns;
      	n = div_u64(tmp, 42);
      	n -= 1;
      	reg_val = (1 << 31) | n;
      	sunxi_set_reg(LEDC_WAIT_TIME1_CTRL_REG, reg_val);
      }
      
      static inline void sunxi_set_wait_data_time_ns(struct sunxi_led *led)
      {
      	u32 min, max;
      #ifndef SUNXI_FPGA_LEDC
      	u32 mask = 0x1FFF, shift = 16, reg_val = 0, n;
      #endif
      	min = SUNXI_WAIT_DATA_TIME_MIN_NS;
      #ifdef SUNXI_FPGA_LEDC
      	/*
      	 * For FPGA platforms, it is easy to meet wait data timeout for
      	 * the obvious latency of task which is because of less cpu cores
      	 * and lower cpu frequency compared with IC platforms, so here we
      	 * permit long enough time latency.
      	 */
      	max = SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA;
      #else /* SUNXI_FPGA_LEDC */
      	max = SUNXI_WAIT_DATA_TIME_MAX_NS_IC;
      #endif /* SUNXI_FPGA_LEDC */
      
      	if (led->wait_data_time_ns < min || led->wait_data_time_ns > max) {
      		LED_ERR("invalid parameter, wait_data_time_ns should be %u-%u!\n",
      			min, max);
      		return;
      	}
      
      #ifndef SUNXI_FPGA_LEDC
      	n = (led->wait_data_time_ns - 42) / 42;
      	reg_val &= ~(mask << shift);
      	reg_val |= (n << shift);
      	sunxi_set_reg(LEDC_DATA_FINISH_CNT_REG_OFFSET, reg_val);
      #endif /* SUNXI_FPGA_LEDC */
      }
      
      static void sunxi_ledc_set_time(struct sunxi_led *led)
      {
      	sunxi_set_reset_ns(led);
      	sunxi_set_t1h_ns(led);
      	sunxi_set_t1l_ns(led);
      	sunxi_set_t0h_ns(led);
      	sunxi_set_t0l_ns(led);
      	sunxi_set_wait_time0_ns(led);
      	sunxi_set_wait_time1_ns(led);
      	sunxi_set_wait_data_time_ns(led);
      }
      
      static void sunxi_ledc_set_length(struct sunxi_led *led)
      {
      	u32 reg_val;
      	u32 length = led->length;
      
      	if (length == 0)
      		return;
      
      	if (length > led->led_count)
      		return;
      
      	reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
      	reg_val &= ~(0x1FFF << 16);
      	reg_val |=  length << 16;
      	sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
      
      	reg_val = sunxi_get_reg(LED_RESET_TIMING_CTRL_REG_OFFSET);
      	reg_val &= ~0x3FF;
      	reg_val |= length - 1;
      	sunxi_set_reg(LED_RESET_TIMING_CTRL_REG_OFFSET, reg_val);
      }
      
      static void sunxi_ledc_set_output_mode(struct sunxi_led *led, const char *str)
      {
      	u32 val;
      	u32 mask = 0x7;
      	u32 shift = 6;
      	u32 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
      
      	if (str != NULL) {
      		if (!strncmp(str, "GRB", 3))
      			val = SUNXI_OUTPUT_GRB;
      		else if (!strncmp(str, "GBR", 3))
      			val = SUNXI_OUTPUT_GBR;
      		else if (!strncmp(str, "RGB", 3))
      			val = SUNXI_OUTPUT_RGB;
      		else if (!strncmp(str, "RBG", 3))
      			val = SUNXI_OUTPUT_RBG;
      		else if (!strncmp(str, "BGR", 3))
      			val = SUNXI_OUTPUT_BGR;
      		else if (!strncmp(str, "BRG", 3))
      			val = SUNXI_OUTPUT_BRG;
      		else
      			return;
      	} else {
      		val = led->output_mode.val;
      	}
      
      	reg_val &= ~(mask << shift);
      	reg_val |= val;
      
      	sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
      
      	if (str != NULL) {
      		if (strncmp(str, led->output_mode.str, 3))
      			memcpy(led->output_mode.str, str, 3);
      	}
      
      	if (val != led->output_mode.val)
      		led->output_mode.val = val;
      }
      
      static void sunxi_ledc_enable_irq(u32 mask)
      {
      	u32 reg_val = 0;
      
      	reg_val |= mask;
      	sunxi_set_reg(LEDC_INT_CTRL_REG_OFFSET, reg_val);
      }
      
      static void sunxi_ledc_disable_irq(u32 mask)
      {
      	u32 reg_val = 0;
      
      	reg_val = sunxi_get_reg(LEDC_INT_CTRL_REG_OFFSET);
      	reg_val &= ~mask;
      	sunxi_set_reg(LEDC_INT_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_ledc_enable(struct sunxi_led *led)
      {
      	u32 reg_val;
      
      	reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
      	reg_val |=  1;
      	sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_ledc_reset(struct sunxi_led *led)
      {
      	u32 reg_val = sunxi_get_reg(LEDC_CTRL_REG_OFFSET);
      
      	sunxi_ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_FIFO_CPUREQ_INT_EN
      			| LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN
      			| LEDC_GLOBAL_INT_EN);
      
      	if (debug_mask & DEBUG_INFO2) {
      		dprintk(DEBUG_INFO2, "dump reg:\n");
      		led_dump_reg(led, 0, 0x30);
      	}
      
      	reg_val |= 1 << 1;
      	sunxi_set_reg(LEDC_CTRL_REG_OFFSET, reg_val);
      }
      
      #ifdef CONFIG_DEBUG_FS
      static ssize_t reset_ns_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_RESET_TIME_MIN_NS;
      	max = SUNXI_RESET_TIME_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->reset_ns = val;
      	sunxi_set_reset_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, reset_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t reset_ns_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->reset_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations reset_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = reset_ns_write,
      	.read  = reset_ns_read,
      };
      
      static ssize_t t1h_ns_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_T1H_MIN_NS;
      	max = SUNXI_T1H_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		return -EINVAL;
      
      	if (copy_from_user(buffer, buf, count))
      		return -EFAULT;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		return -EINVAL;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->t1h_ns = val;
      
      	sunxi_set_t1h_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, t1h_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t t1h_ns_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->t1h_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations t1h_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = t1h_ns_write,
      	.read  = t1h_ns_read,
      };
      
      static ssize_t t1l_ns_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_T1L_MIN_NS;
      	max = SUNXI_T1L_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->t1l_ns = val;
      	sunxi_set_t1l_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, t1l_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t t1l_ns_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->t1l_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations t1l_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = t1l_ns_write,
      	.read  = t1l_ns_read,
      };
      
      static ssize_t t0h_ns_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_T0H_MIN_NS;
      	max = SUNXI_T0H_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->t0h_ns = val;
      	sunxi_set_t0h_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, t0h_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t t0h_ns_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->t0h_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations t0h_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = t0h_ns_write,
      	.read  = t0h_ns_read,
      };
      
      static ssize_t t0l_ns_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_T0L_MIN_NS;
      	max = SUNXI_T0L_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->t0l_ns = val;
      	sunxi_set_t0l_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, t0l_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t t0l_ns_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->t0l_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations t0l_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = t0l_ns_write,
      	.read  = t0l_ns_read,
      };
      
      static ssize_t wait_time0_ns_write(struct file *filp, const char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_WAIT_TIME0_MIN_NS;
      	max = SUNXI_WAIT_TIME0_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->wait_time0_ns = val;
      	sunxi_set_wait_time0_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, wait_time0_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t wait_time0_ns_read(struct file *filp, char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->wait_time0_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations wait_time0_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = wait_time0_ns_write,
      	.read  = wait_time0_ns_read,
      };
      
      static ssize_t wait_time1_ns_write(struct file *filp, const char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min;
      	unsigned long long max;
      	unsigned long long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_WAIT_TIME1_MIN_NS;
      	max = SUNXI_WAIT_TIME1_MAX_NS;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoull(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->wait_time1_ns = val;
      	sunxi_set_wait_time1_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, wait_time1_ns should be %u-%lld!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t wait_time1_ns_read(struct file *filp, char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%lld\n", led->wait_time1_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations wait_time1_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = wait_time1_ns_write,
      	.read  = wait_time1_ns_read,
      };
      
      static ssize_t wait_data_time_ns_write(struct file *filp,
      				const char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int err;
      	char buffer[64];
      	u32 min, max;
      	unsigned long val;
      	struct sunxi_led *led = sunxi_led_global;
      
      	min = SUNXI_WAIT_DATA_TIME_MIN_NS;
      #ifdef SUNXI_FPGA_LEDC
      	max = SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA;
      #else
      	max = SUNXI_WAIT_DATA_TIME_MAX_NS_IC;
      #endif
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	err = kstrtoul(buffer, 10, &val);
      	if (err)
      		goto err_out;
      
      	if (val < min || val > max)
      		goto err_out;
      
      	led->wait_data_time_ns = val;
      	sunxi_set_wait_data_time_ns(led);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter, wait_data_time_ns should be %u-%u!\n",
      		min, max);
      
      	return -EINVAL;
      }
      
      static ssize_t wait_data_time_ns_read(struct file *filp, char __user *buf,
      				size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%u\n", led->wait_data_time_ns);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations wait_data_time_ns_fops = {
      	.owner = THIS_MODULE,
      	.write = wait_data_time_ns_write,
      	.read  = wait_data_time_ns_read,
      };
      
      static int data_show(struct seq_file *s, void *data)
      {
      	int i;
      	struct sunxi_led *led = sunxi_led_global;
      
      	for (i = 0; i < led->led_count; i++) {
      		if (!(i % 4)) {
      			if (i + 4 <= led->led_count)
      				seq_printf(s, "%04d-%04d", i, i + 4);
      			else
      				seq_printf(s, "%04d-%04d", i, led->led_count);
      		}
      		seq_printf(s, " 0x%08x", led->data[i]);
      		if (((i % 4) == 3) || (i == led->led_count - 1))
      			seq_puts(s, "\n");
      	}
      
      	return 0;
      }
      
      static int data_open(struct inode *inode, struct file *file)
      {
      	return single_open(file, data_show, inode->i_private);
      }
      
      static const struct file_operations data_fops = {
      	.owner = THIS_MODULE,
      	.open  = data_open,
      	.read = seq_read,
      	.llseek = seq_lseek,
      	.release = single_release,
      };
      
      static ssize_t output_mode_write(struct file *filp, const char __user *buf,
      			size_t count, loff_t *offp)
      {
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	if (count >= sizeof(buffer))
      		goto err_out;
      
      	if (copy_from_user(buffer, buf, count))
      		goto err_out;
      
      	buffer[count] = '\0';
      
      	sunxi_ledc_set_output_mode(led, buffer);
      
      	*offp += count;
      
      	return count;
      
      err_out:
      	LED_ERR("invalid parameter!\n");
      
      	return -EINVAL;
      }
      
      static ssize_t output_mode_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	struct sunxi_led *led = sunxi_led_global;
      
      	r = snprintf(buffer, 64, "%s\n", led->output_mode.str);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations output_mode_fops = {
      	.owner = THIS_MODULE,
      	.write = output_mode_write,
      	.read  = output_mode_read,
      };
      
      static ssize_t hwversion_read(struct file *filp, char __user *buf,
      			size_t count, loff_t *offp)
      {
      	int r;
      	char buffer[64];
      	u32 reg_val, major_ver, minor_ver;
      
      	reg_val = sunxi_get_reg(LEDC_VER_NUM_REG);
      	major_ver = reg_val >> 16;
      	minor_ver = reg_val & 0xF;
      
      	r = snprintf(buffer, 64, "r%up%u\n", major_ver, minor_ver);
      
      	return simple_read_from_buffer(buf, count, offp, buffer, r);
      }
      
      static const struct file_operations hwversion_fops = {
      	.owner = THIS_MODULE,
      	.read  = hwversion_read,
      };
      
      static void sunxi_led_create_debugfs(struct sunxi_led *led)
      {
      	struct dentry *debugfs_dir, *debugfs_file;
      
      	debugfs_dir = debugfs_create_dir("sunxi_leds", NULL);
      	if (IS_ERR_OR_NULL(debugfs_dir)) {
      		LED_ERR("debugfs_create_dir failed!\n");
      		return;
      	}
      
      	led->debugfs_dir = debugfs_dir;
      
      	debugfs_file = debugfs_create_file("reset_ns", 0660,
      				debugfs_dir, NULL, &reset_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for reset_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("t1h_ns", 0660,
      				debugfs_dir, NULL, &t1h_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for t1h_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("t1l_ns", 0660,
      				debugfs_dir, NULL, &t1l_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for t1l_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("t0h_ns", 0660,
      				debugfs_dir, NULL, &t0h_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for t0h_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("t0l_ns", 0660,
      				debugfs_dir, NULL, &t0l_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for t0l_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("wait_time0_ns", 0660,
      				debugfs_dir, NULL, &wait_time0_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for wait_time0_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("wait_time1_ns", 0660,
      				debugfs_dir, NULL, &wait_time1_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for wait_time1_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("wait_data_time_ns", 0660,
      				debugfs_dir, NULL, &wait_data_time_ns_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for wait_data_time_ns failed!\n");
      
      	debugfs_file = debugfs_create_file("data", 0440,
      				debugfs_dir, NULL, &data_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for data failed!\n");
      
      	debugfs_file = debugfs_create_file("output_mode", 0660,
      				debugfs_dir, NULL, &output_mode_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for output_mode failed!\n");
      
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for trans_mode failed!\n");
      
      	debugfs_file = debugfs_create_file("hwversion", 0440,
      				debugfs_dir, NULL, &hwversion_fops);
      	if (!debugfs_file)
      		LED_ERR("debugfs_create_file for hwversion failed!\n");
      }
      
      static void sunxi_led_remove_debugfs(struct sunxi_led *led)
      {
      	debugfs_remove_recursive(led->debugfs_dir);
      }
      #endif /* CONFIG_DEBUG_FS */
      
      static void sunxi_ledc_set_dma_mode(struct sunxi_led *led)
      {
      	u32 reg_val = 0;
      
      	reg_val |= 1 << 5;
      	sunxi_set_reg(LEDC_DMA_CTRL_REG, reg_val);
      
      	sunxi_ledc_disable_irq(LEDC_FIFO_CPUREQ_INT_EN);
      }
      
      static void sunxi_ledc_set_cpu_mode(struct sunxi_led *led)
      {
      	u32 reg_val = 0;
      
      	reg_val &= ~(1 << 5);
      	sunxi_set_reg(LEDC_DMA_CTRL_REG, reg_val);
      
      	sunxi_ledc_enable_irq(LEDC_FIFO_CPUREQ_INT_EN);
      }
      
      static void sunxi_ledc_dma_callback(void *param)
      {
      	dprintk(DEBUG_INFO, "finish\n");
      }
      
      static void sunxi_ledc_trans_data(struct sunxi_led *led)
      {
      	int i, err;
      	size_t size;
      	unsigned long flags;
      	phys_addr_t dst_addr;
      	struct dma_slave_config slave_config;
      	struct device *dev = led->dev;
      	struct dma_async_tx_descriptor *dma_desc;
      
      	/* less than 32 lights use cpu transmission. */
      	/* more than 32 lights use dma transmission. */
      	if (led->length <= SUNXI_LEDC_FIFO_DEPTH) {
      		dprintk(DEBUG_INFO, "cpu xfer\n");
      		ktime_get_coarse_real_ts64(&(led->start_time));
      		sunxi_ledc_set_time(led);
      		sunxi_ledc_set_output_mode(led, led->output_mode.str);
      		sunxi_ledc_set_cpu_mode(led);
      		sunxi_ledc_set_length(led);
      
      		sunxi_ledc_enable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
      				| LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN);
      
      		sunxi_ledc_enable(led);
      
      		for (i = 0; i < led->length; i++)
      			sunxi_set_reg(LEDC_DATA_REG_OFFSET, led->data[i]);
      
      	} else {
      		dprintk(DEBUG_INFO, "dma xfer\n");
      
      		size = led->length * 4;
      		led->src_dma = dma_map_single(dev, led->data,
      					size, DMA_TO_DEVICE);
      		dst_addr = led->res->start + LEDC_DATA_REG_OFFSET;
      
      		flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
      
      		slave_config.direction = DMA_MEM_TO_DEV;
      		slave_config.src_addr = led->src_dma;
      		slave_config.dst_addr = dst_addr;
      		slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
      		slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
      		slave_config.src_maxburst = 4;
      		slave_config.dst_maxburst = 4;
      
      		err = dmaengine_slave_config(led->dma_chan, &slave_config);
      		if (err < 0) {
      			LED_ERR("dmaengine_slave_config failed!\n");
      			return;
      		}
      
      		dma_desc = dmaengine_prep_slave_single(led->dma_chan,
      							led->src_dma,
      							size,
      							DMA_MEM_TO_DEV,
      							flags);
      		if (!dma_desc) {
      			LED_ERR("dmaengine_prep_slave_single failed!\n");
      			return;
      		}
      
      		dma_desc->callback = sunxi_ledc_dma_callback;
      
      		dmaengine_submit(dma_desc);
      		dma_async_issue_pending(led->dma_chan);
      
      		ktime_get_coarse_real_ts64(&(led->start_time));
      		sunxi_ledc_set_time(led);
      		sunxi_ledc_set_output_mode(led, led->output_mode.str);
      		sunxi_ledc_set_dma_mode(led);
      		sunxi_ledc_set_length(led);
      		sunxi_ledc_enable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN
      				| LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN);
      		sunxi_ledc_enable(led);
      	}
      }
      
      static inline void sunxi_ledc_clear_all_irq(void)
      {
      	u32 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
      
      	reg_val &= ~0x1F;
      	sunxi_set_reg(LEDC_INT_STS_REG_OFFSET, reg_val);
      }
      
      static inline void sunxi_ledc_clear_irq(enum sunxi_ledc_irq_status_reg irq)
      {
      	u32 reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
      
      	reg_val &= ~irq;
      	sunxi_set_reg(LEDC_INT_STS_REG_OFFSET, reg_val);
      }
      
      static int sunxi_ledc_complete(struct sunxi_led *led)
      {
      	unsigned long flags = 0;
      	unsigned long timeout = 0;
      	u32 reg_val;
      
      	/*wait_event_timeout return 0   : timeout
      	 *wait_event_timeout return > 0 : thr left time
      	 * */
      	timeout = wait_event_timeout(led->wait, led->result, 5*HZ);
      	if (timeout == 0) {
      		reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
      		pr_err("LEDC INTERRUPT STATUS REG IS %x", reg_val);
      		LED_ERR("led xfer timeout\n");
      		reg_val = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
      		pr_err("LEDC INTERRUPT STATUS REG IS %x", reg_val);
      		return -ETIME;
      	} else if (led->result == RESULT_ERR) {
      		return -ECOMM;
      	}
      
      	dprintk(DEBUG_INFO, "xfer complete\n");
      
      	spin_lock_irqsave(&led->lock, flags);
      	led->result = 0;
      	spin_unlock_irqrestore(&led->lock, flags);
      
      	return 0;
      }
      
      static irqreturn_t sunxi_ledc_irq_handler(int irq, void *dev_id)
      {
      	long delta_time_ns;
      	u32 irq_status, max_ns;
      	struct sunxi_led *led = sunxi_led_global;
      	struct device *dev = led->dev;
      	struct timespec64 current_time;
      
      	spin_lock(&led->lock);
      
      	irq_status = sunxi_get_reg(LEDC_INT_STS_REG_OFFSET);
      
      	sunxi_ledc_clear_all_irq();
      
      	if (irq_status & LEDC_TRANS_FINISH_INT) {
      		sunxi_ledc_reset(led);
      		led->result = RESULT_COMPLETE;
      		goto out;
      	}
      
      	if (irq_status & LEDC_WAITDATA_TIMEOUT_INT) {
      		ktime_get_coarse_real_ts64(&current_time);
      		delta_time_ns = current_time.tv_sec - led->start_time.tv_sec;
      		delta_time_ns *= 1000 * 1000 * 1000;
      		delta_time_ns += current_time.tv_nsec - led->start_time.tv_nsec;
      
      		max_ns = led->wait_data_time_ns;
      
      		if (delta_time_ns <= max_ns) {
      			spin_unlock(&led->lock);
      			return IRQ_HANDLED;
      		}
      
      		sunxi_ledc_reset(led);
      
      		if (delta_time_ns <= max_ns * 2) {
      			sunxi_ledc_trans_data(led);
      		} else {
      			LED_ERR("wait time is more than %d ns,"
      				"going to reset ledc and drop this operation!\n",
      				max_ns);
      			led->result = RESULT_ERR;
      		}
      
      		goto out;
      	}
      
      	if (irq_status & LEDC_FIFO_OVERFLOW_INT) {
      		LED_ERR("there exists fifo overflow issue, irq_status=0x%x!\n",
      				irq_status);
      		sunxi_ledc_reset(led);
      		led->result = RESULT_ERR;
      		goto out;
      	}
      
      out:
      	if (led->dma_chan)
      		dma_unmap_single(dev, led->src_dma, led->length * 4, DMA_TO_DEVICE);
      	wake_up(&led->wait);
      	led->length = 0;
      	spin_unlock(&led->lock);
      	return IRQ_HANDLED;
      }
      
      static int sunxi_ledc_irq_init(struct sunxi_led *led)
      {
      	int err;
      	struct device *dev = led->dev;
      	unsigned long flags = 0;
      	const char *name = "ledcirq";
      	struct platform_device *pdev;
      
      	pdev = container_of(dev, struct platform_device, dev);
      
      	spin_lock_init(&led->lock);
      
      	led->irqnum = platform_get_irq(pdev, 0);
      	if (led->irqnum < 0)
      		LED_ERR("failed to get ledc irq!\n");
      
      	err = request_irq(led->irqnum, sunxi_ledc_irq_handler,
      				flags, name, dev);
      	if (err) {
      		LED_ERR("failed to install IRQ handler for irqnum %d\n",
      			led->irqnum);
      		return -EPERM;
      	}
      
      	return 0;
      }
      
      static void sunxi_ledc_irq_deinit(struct sunxi_led *led)
      {
      	free_irq(led->irqnum, led->dev);
      	sunxi_ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_FIFO_CPUREQ_INT_EN
      			| LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN
      			| LEDC_GLOBAL_INT_EN);
      }
      
      static void sunxi_ledc_pinctrl_init(struct sunxi_led *led)
      {
      	struct device *dev = led->dev;
      	struct pinctrl *pinctrl = devm_pinctrl_get_select_default(dev);
      
      	led->pctrl = pinctrl;
      	if (IS_ERR(pinctrl))
      		LED_ERR("devm_pinctrl_get_select_default failed!\n");
      }
      
      static int led_regulator_request(struct sunxi_led *led)
      {
      	struct regulator *regu = NULL;
      
      	/* Consider "n*" as nocare. Support "none", "nocare", "null", "" etc. */
      	if ((led->regulator_id[0] == 'n') || (led->regulator_id[0] == 0))
      		return 0;
      
      	regu = regulator_get(NULL, led->regulator_id);
      	if (IS_ERR(regu)) {
      		LED_ERR("get regulator %s failed!\n", led->regulator_id);
      		return -1;
      	}
      	led->regulator = regu;
      
      	return 0;
      }
      
      static int led_regulator_release(struct sunxi_led *led)
      {
      	if (led->regulator == NULL)
      		return 0;
      
      	regulator_put(led->regulator);
      	led->regulator = NULL;
      
      	return 1;
      }
      
      static int sunxi_ledc_dma_get(struct sunxi_led *led)
      {
      	if (led->dma_chan == NULL) {
      		led->dma_chan = dma_request_chan(led->dev, "tx");
      		if (IS_ERR(led->dma_chan)) {
      			LED_ERR("failed to get the DMA channel!\n");
      			return -EFAULT;
      		}
      	}
      	return 0;
      }
      
      static int sunxi_set_led_brightness(struct led_classdev *led_cdev,
      			enum led_brightness value)
      {
      	unsigned long flags;
      	u32 r, g, b, shift, old_data, new_data, length;
      	struct sunxi_led_info *pinfo;
      	struct sunxi_led_classdev_group *pcdev_group;
      	struct sunxi_led *led = sunxi_led_global;
      	int err;
      
      	pinfo = container_of(led_cdev, struct sunxi_led_info, cdev);
      
      	switch (pinfo->type) {
      	case LED_TYPE_G:
      		pcdev_group = container_of(pinfo,
      			struct sunxi_led_classdev_group, g);
      		g = value;
      		shift = 16;
      		break;
      	case LED_TYPE_R:
      		pcdev_group = container_of(pinfo,
      			struct sunxi_led_classdev_group, r);
      		r = value;
      		shift = 8;
      		break;
      
      	case LED_TYPE_B:
      		pcdev_group = container_of(pinfo,
      			struct sunxi_led_classdev_group, b);
      		b = value;
      		shift = 0;
      		break;
      	}
      
      	old_data = led->data[pcdev_group->led_num];
      	if (((old_data >> shift) & 0xFF) == value)
      		return 0;
      
      	if (pinfo->type != LED_TYPE_R)
      		r = pcdev_group->r.cdev.brightness;
      	if (pinfo->type != LED_TYPE_G)
      		g = pcdev_group->g.cdev.brightness;
      	if (pinfo->type != LED_TYPE_B)
      		b = pcdev_group->b.cdev.brightness;
      
      	/* LEDC treats input data as GRB by default */
      	new_data = (g << 16) | (r << 8) | b;
      	length = pcdev_group->led_num + 1;
      
      	spin_lock_irqsave(&led->lock, flags);
      	led->data[pcdev_group->led_num] = new_data;
      	led->length = length;
      	spin_unlock_irqrestore(&led->lock, flags);
      
      	/* prepare for dma xfer, dynamic apply dma channel */
      	if (led->length > SUNXI_LEDC_FIFO_DEPTH) {
      		err = sunxi_ledc_dma_get(led);
      		if (err)
      			return err;
      	}
      
      	sunxi_ledc_trans_data(led);
      	if (debug_mask & DEBUG_INFO2) {
      		dprintk(DEBUG_INFO2, "dump reg:\n");
      		led_dump_reg(led, 0, 0x30);
      	}
      
      	sunxi_ledc_complete(led);
      
      	if (debug_mask & DEBUG_INFO1)
      		pr_warn("num = %03u\n", length);
      
      	return 0;
      }
      
      static int sunxi_register_led_classdev(struct sunxi_led *led)
      {
      	int i, err;
      	size_t size;
      	struct device *dev = led->dev;
      	struct led_classdev *pcdev_RGB;
      
      	dprintk(DEBUG_INIT, "led_classdev start\n");
      	if (!led->led_count)
      		led->led_count = SUNXI_DEFAULT_LED_COUNT;
      
      	size = sizeof(struct sunxi_led_classdev_group) * led->led_count;
      	led->pcdev_group = devm_kzalloc(dev, size, GFP_KERNEL);
      	if (!led->pcdev_group)
      		return -ENOMEM;
      
      	for (i = 0; i < led->led_count; i++) {
      		led->pcdev_group[i].r.type = LED_TYPE_R;
      		pcdev_RGB = &led->pcdev_group[i].r.cdev;
      		pcdev_RGB->name = devm_kzalloc(dev, 16, GFP_KERNEL);
      		if (!pcdev_RGB->name)
      			return -ENOMEM;
      		sprintf((char *)pcdev_RGB->name, "sunxi_led%dr", i);
      		pcdev_RGB->brightness = LED_OFF;
      		pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
      		pcdev_RGB->dev = dev;
      		err = led_classdev_register(dev, pcdev_RGB);
      		if (err < 0) {
      			LED_ERR("led_classdev_register %s failed!\n",
      				pcdev_RGB->name);
      			return err;
      		}
      
      		led->pcdev_group[i].g.type = LED_TYPE_G;
      		pcdev_RGB = &led->pcdev_group[i].g.cdev;
      		pcdev_RGB->name = devm_kzalloc(dev, 16, GFP_KERNEL);
      		if (!pcdev_RGB->name)
      			return -ENOMEM;
      		sprintf((char *)pcdev_RGB->name, "sunxi_led%dg", i);
      		pcdev_RGB->brightness = LED_OFF;
      		pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
      		pcdev_RGB->dev = dev;
      		err = led_classdev_register(dev, pcdev_RGB);
      		if (err < 0) {
      			LED_ERR("led_classdev_register %s failed!\n",
      			pcdev_RGB->name);
      			return err;
      		}
      
      		led->pcdev_group[i].b.type = LED_TYPE_B;
      		pcdev_RGB = &led->pcdev_group[i].b.cdev;
      		pcdev_RGB->name = devm_kzalloc(dev, 16, GFP_KERNEL);
      		if (!pcdev_RGB->name)
      			return -ENOMEM;
      		sprintf((char *)pcdev_RGB->name, "sunxi_led%db", i);
      		pcdev_RGB->brightness = LED_OFF;
      		pcdev_RGB->brightness_set_blocking = sunxi_set_led_brightness;
      		pcdev_RGB->dev = dev;
      		err = led_classdev_register(dev, pcdev_RGB);
      		if (err < 0) {
      			LED_ERR("led_classdev_register %s failed!\n",
      					pcdev_RGB->name);
      			return err;
      		}
      
      		led->pcdev_group[i].led_num = i;
      	}
      
      	size = sizeof(u32) * led->led_count;
      	led->data = devm_kzalloc(dev, size, GFP_KERNEL);
      	if (!led->data)
      		return -ENOMEM;
      
      	return 0;
      }
      
      static void sunxi_unregister_led_classdev(struct sunxi_led *led)
      {
      	int i;
      
      	for (i = 0; i < led->led_count; i++) {
      		kfree(led->pcdev_group[i].b.cdev.name);
      		led->pcdev_group[i].b.cdev.name = NULL;
      		kfree(led->pcdev_group[i].g.cdev.name);
      		led->pcdev_group[i].g.cdev.name = NULL;
      		kfree(led->pcdev_group[i].r.cdev.name);
      		led->pcdev_group[i].r.cdev.name = NULL;
      		led_classdev_unregister(&led->pcdev_group[i].b.cdev);
      		led_classdev_unregister(&led->pcdev_group[i].g.cdev);
      		led_classdev_unregister(&led->pcdev_group[i].r.cdev);
      	}
      	kfree(led->data);
      	led->data = NULL;
      
      
      	kfree(led->pcdev_group);
      	led->pcdev_group = NULL;
      }
      
      static inline int sunxi_get_u32_of_property(const char *propname, int *val)
      {
      	int err;
      	struct sunxi_led *led = sunxi_led_global;
      	struct device *dev = led->dev;
      	struct device_node *np = dev->of_node;
      
      	err = of_property_read_u32(np, propname, val);
      	if (err < 0)
      		LED_ERR("failed to get the value of propname %s!\n", propname);
      
      	return err;
      }
      
      static inline int sunxi_get_str_of_property(const char *propname,
      					const char **out_string)
      {
      	int err;
      	struct sunxi_led *led = sunxi_led_global;
      	struct device *dev = led->dev;
      	struct device_node *np = dev->of_node;
      
      	err = of_property_read_string(np, propname, out_string);
      	if (err < 0)
      		LED_ERR("failed to get the string of propname %s!\n", propname);
      
      	return err;
      }
      
      static void sunxi_get_para_of_property(struct sunxi_led *led)
      {
      	int err;
      	u32 val;
      	const char *str;
      
      	err = sunxi_get_u32_of_property("led_count", &val);
      	if (!err)
      		led->led_count = val;
      
      	memcpy(led->output_mode.str, "GRB", 3);
      	led->output_mode.val = SUNXI_OUTPUT_GRB;
      	err = sunxi_get_str_of_property("output_mode", &str);
      	if (!err)
      		if (!strncmp(str, "BRG", 3) ||
      			!strncmp(str, "GBR", 3) ||
      			!strncmp(str, "RGB", 3) ||
      			!strncmp(str, "RBG", 3) ||
      			!strncmp(str, "BGR", 3))
      			memcpy(led->output_mode.str, str, 3);
      
      	err =  sunxi_get_str_of_property("led_regulator", &str);
      	if (!err) {
      		if (strlen(str) >= sizeof(led->regulator_id))
      			LED_ERR("illegal regulator id\n");
      		else {
      			strcpy(led->regulator_id, str);
      			pr_info("led_regulator: %s\n", led->regulator_id);
      		}
      	}
      
      	err = sunxi_get_u32_of_property("reset_ns", &val);
      	if (!err)
      		led->reset_ns = val;
      
      	err = sunxi_get_u32_of_property("t1h_ns", &val);
      	if (!err)
      		led->t1h_ns = val;
      
      	err = sunxi_get_u32_of_property("t1l_ns", &val);
      	if (!err)
      		led->t1l_ns = val;
      
      	err = sunxi_get_u32_of_property("t0h_ns", &val);
      	if (!err)
      		led->t0h_ns = val;
      
      	err = sunxi_get_u32_of_property("t0l_ns", &val);
      	if (!err)
      		led->t0l_ns = val;
      
      	err = sunxi_get_u32_of_property("wait_time0_ns", &val);
      	if (!err)
      		led->wait_time0_ns = val;
      
      	err = sunxi_get_u32_of_property("wait_time1_ns", &val);
      	if (!err)
      		led->wait_time1_ns = val;
      
      	err = sunxi_get_u32_of_property("wait_data_time_ns", &val);
      	if (!err)
      		led->wait_data_time_ns = val;
      }
      static void sunxi_led_set_all(struct sunxi_led *led, u8 channel,
      		enum led_brightness value)
      {
      	u32 i;
      	struct led_classdev *led_cdev;
      
      	if (channel%3 == 0) {
      		for (i = 0; i < led->led_count; i++) {
      			led_cdev = &led->pcdev_group[i].r.cdev;
      			mutex_lock(&led_cdev->led_access);
      			sunxi_set_led_brightness(led_cdev, value);
      			mutex_unlock(&led_cdev->led_access);
      		}
      	} else if (channel%3 == 1) {
      		for (i = 0; i < led->led_count; i++) {
      			led_cdev = &led->pcdev_group[i].g.cdev;
      			mutex_lock(&led_cdev->led_access);
      			sunxi_set_led_brightness(led_cdev, value);
      			mutex_unlock(&led_cdev->led_access);
      		}
      	} else {
      		for (i = 0; i < led->led_count; i++) {
      			led_cdev = &led->pcdev_group[i].b.cdev;
      			mutex_lock(&led_cdev->led_access);
      			sunxi_set_led_brightness(led_cdev, value);
      			mutex_unlock(&led_cdev->led_access);
      		}
      	}
      }
      
      static ssize_t led_show(struct class *class,
      			struct class_attribute *attr,
      			char *buf)
      {
      	struct sunxi_led *led = sunxi_led_global;
      
      	sunxi_led_set_all(led, 0, 0);
      	sunxi_led_set_all(led, 1, 0);
      	sunxi_led_set_all(led, 2, 0);
      
      	sunxi_led_set_all(led, 0, 20);
      	msleep(500);
      	sunxi_led_set_all(led, 1, 20);
      	msleep(500);
      	sunxi_led_set_all(led, 2, 20);
      	msleep(500);
      
      	sunxi_led_set_all(led, 0, 0);
      	sunxi_led_set_all(led, 1, 0);
      	sunxi_led_set_all(led, 2, 0);
      
      	return 0;
      }
      
      static struct class_attribute led_class_attrs[] = {
      	__ATTR(light, 0644, led_show, NULL),
      	//__ATTR_NULL,
      };
      
      static void led_node_init(void)
      {
      	int i;
      	int err;
      	/* sys/class/led/xxx */
      	for (i = 0; i < ARRAY_SIZE(led_class_attrs); i++) {
      		err = class_create_file(led_class, &led_class_attrs[i]);
      		if (err) {
      			LED_ERR("class_create_file() failed!\n");
      			while (i--)
      				class_remove_file(led_class, &led_class_attrs[i]);
      			class_destroy(led_class);
      			led_class = NULL;
      		}
      	}
      }
      
      static int sunxi_led_probe(struct platform_device *pdev)
      {
      	int err;
      	struct sunxi_led *led;
      	struct device *dev = &pdev->dev;
      	struct resource *mem_res = NULL;
      	int ret;
      
      	dprintk(DEBUG_INIT, "start\n");
      
      	led = devm_kzalloc(dev, sizeof(struct sunxi_led), GFP_KERNEL);
      	if (!led)
      		return -ENOMEM;
      
      	sunxi_led_global = led;
      
      	platform_set_drvdata(pdev, led);
      	led->dev = dev;
      
      	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
      	if (mem_res == NULL) {
      		LED_ERR("failed to get MEM res\n");
      		ret = -ENXIO;
      		goto emem;
      	}
      
      	if (!request_mem_region(mem_res->start, resource_size(mem_res),
      				mem_res->name)) {
      		LED_ERR("failed to request mem region\n");
      		ret = -EINVAL;
      		goto emem;
      	}
      
      	led->iomem_reg_base = ioremap(mem_res->start, resource_size(mem_res));
      	if (!led->iomem_reg_base) {
      		ret = -EIO;
      		goto eiomap;
      	}
      	led->res = mem_res;
      
      	led->output_mode.str = devm_kzalloc(dev, 3, GFP_KERNEL);
      	if (!led->output_mode.str) {
      		ret = -ENOMEM;
      		goto ezalloc_str;
      	}
      
      	sunxi_get_para_of_property(led);
      
      	err = led_regulator_request(led);
      	if (err < 0) {
      		LED_ERR("request regulator failed!\n");
      		ret = err;
      		goto eregulator;
      	}
      
      	err = sunxi_register_led_classdev(led);
      	if (err) {
      		LED_ERR("failed to register led classdev\n");
      		ret = err;
      		goto eclassdev;
      	}
      
      	sunxi_ledc_set_time(led);
      
      	led->reset = devm_reset_control_get(&pdev->dev, NULL);
      	if (IS_ERR(led->reset)) {
      		LED_ERR("get reset clk error\n");
      		return -EINVAL;
      	}
      	ret = reset_control_deassert(led->reset);
      	if (ret) {
      		LED_ERR("deassert clk error, ret:%d\n", ret);
      		return ret;
      	}
      
      	sunxi_clk_init(led);
      
      	init_waitqueue_head(&led->wait);
      
      	err = sunxi_ledc_irq_init(led);
      	if (err) {
      		LED_ERR("failed to init irq\n");
      		ret = err;
      		goto eirq;
      	}
      
      	sunxi_ledc_pinctrl_init(led);
      
      #ifdef CONFIG_DEBUG_FS
      	sunxi_led_create_debugfs(led);
      #endif /* CONFIG_DEBUG_FS */
      
      	led_class = class_create(THIS_MODULE, "led");
      	if (IS_ERR(led_class)) {
      		LED_ERR("class_register err\n");
      		class_destroy(led_class);
      		ret = -EFAULT;
      		goto eclass;
      	}
      	led_node_init();
      	dprintk(DEBUG_INIT, "finish\n");
      	return 0;
      
      eclass:
      #ifdef CONFIG_DEBUG_FS
      	sunxi_led_remove_debugfs(led);
      #endif /* CONFIG_DEBUG_FS */
      
      	sunxi_ledc_irq_deinit(led);
      
      eirq:
      	sunxi_unregister_led_classdev(led);
      	sunxi_clk_deinit(led);
      
      eclassdev:
      	led_regulator_release(led);
      
      eregulator:
      	kfree(led->output_mode.str);
      
      ezalloc_str:
      	iounmap(led->iomem_reg_base);
      	led->iomem_reg_base = NULL;
      
      eiomap:
      	release_mem_region(mem_res->start, resource_size(mem_res));
      
      emem:
      	kfree(led);
      	return ret;
      }
      
      static int sunxi_led_remove(struct platform_device *pdev)
      {
      	struct sunxi_led *led = platform_get_drvdata(pdev);
      
      	class_destroy(led_class);
      
      #ifdef CONFIG_DEBUG_FS
      	sunxi_led_remove_debugfs(led);
      #endif /* CONFIG_DEBUG_FS */
      
      	if (led->dma_chan) {
      		dmaengine_terminate_all(led->dma_chan);
      		dma_release_channel(led->dma_chan);
      		led->dma_chan = NULL;
      	}
      
      	sunxi_ledc_irq_deinit(led);
      
      	sunxi_unregister_led_classdev(led);
      	sunxi_clk_deinit(led);
      
      	led_regulator_release(led);
      
      	kfree(led->output_mode.str);
      	led->output_mode.str = NULL;
      
      	iounmap(led->iomem_reg_base);
      	led->iomem_reg_base = NULL;
      
      	release_mem_region(led->res->start, resource_size(led->res));
      
      	kfree(led);
      	led = NULL;
      
      	dprintk(DEBUG_INIT, "finish\n");
      	return 0;
      }
      
      #if IS_ENABLED(CONFIG_PM)
      static inline void sunxi_led_save_regs(struct sunxi_led *led)
      {
      	int i;
      
      	for (i = 0; i < ARRAY_SIZE(sunxi_led_regs_offset); i++)
      		led->regs_backup[i] = readl(led->iomem_reg_base + sunxi_led_regs_offset[i]);
      }
      
      static inline void sunxi_led_restore_regs(struct sunxi_led *led)
      {
      	int i;
      
      	for (i = 0; i < ARRAY_SIZE(sunxi_led_regs_offset); i++)
      		writel(led->regs_backup[i], led->iomem_reg_base + sunxi_led_regs_offset[i]);
      }
      
      static void sunxi_led_enable_irq(struct sunxi_led *led)
      {
      	enable_irq(led->irqnum);
      }
      
      static void sunxi_led_disable_irq(struct sunxi_led *led)
      {
      	disable_irq_nosync(led->irqnum);
      }
      
      static int sunxi_led_gpio_state_select(struct sunxi_led *led, char *name)
      {
      	int err;
      	struct pinctrl_state *pctrl_state;
      
      	pctrl_state = pinctrl_lookup_state(led->pctrl, name);
      	if (IS_ERR(pctrl_state)) {
      		dev_err(led->dev, "pinctrl_lookup_state(%s) failed! return %p\n",
      				name, pctrl_state);
      		return PTR_ERR(pctrl_state);
      	}
      
      	err = pinctrl_select_state(led->pctrl, pctrl_state);
      	if (err < 0) {
      		dev_err(led->dev, "pinctrl_select_state(%s) failed! return %d\n",
      				name, err);
      		return err;
      	}
      
      	return 0;
      }
      
      static void sunxi_led_enable_clk(struct sunxi_led *led)
      {
      	clk_prepare_enable(led->clk_ledc);
      	clk_prepare_enable(led->clk_cpuapb);
      }
      
      static void sunxi_led_disable_clk(struct sunxi_led *led)
      {
      	clk_disable_unprepare(led->clk_cpuapb);
      	clk_disable_unprepare(led->clk_ledc);
      }
      
      static int sunxi_led_power_on(struct sunxi_led *led)
      {
      	int err;
      
      	if (led->regulator == NULL)
      		return 0;
      
      	err = regulator_enable(led->regulator);
      	if (err) {
      		dev_err(led->dev, "enable regulator %s failed!\n", led->regulator_id);
      		return err;
      	}
      	return 0;
      }
      
      static int sunxi_led_power_off(struct sunxi_led *led)
      {
      	int err;
      
      	if (led->regulator == NULL)
      		return 0;
      
      	err = regulator_disable(led->regulator);
      	if (err) {
      		dev_err(led->dev, "disable regulator %s failed!\n", led->regulator_id);
      		return err;
      	}
      	return 0;
      }
      
      static int sunxi_led_suspend(struct device *dev)
      {
      	struct platform_device *pdev = to_platform_device(dev);
      	struct sunxi_led *led = platform_get_drvdata(pdev);
      
      	dev_dbg(led->dev, "[%s] enter standby\n", __func__);
      
      	sunxi_led_disable_irq(led);
      
      	sunxi_led_save_regs(led);
      
      	sunxi_led_gpio_state_select(led, PINCTRL_STATE_SLEEP);
      
      	sunxi_led_disable_clk(led);
      
      	reset_control_assert(led->reset);
      
      	sunxi_led_power_off(led);
      
      	return 0;
      }
      
      static int sunxi_led_resume(struct device *dev)
      {
      	struct platform_device *pdev = to_platform_device(dev);
      	struct sunxi_led *led = platform_get_drvdata(pdev);
      
      	dev_dbg(led->dev, "[%s] return from standby\n", __func__);
      
      	sunxi_led_power_on(led);
      
      	reset_control_deassert(led->reset);
      
      	sunxi_led_enable_clk(led);
      
      	sunxi_led_gpio_state_select(led, PINCTRL_STATE_DEFAULT);
      
      	sunxi_led_restore_regs(led);
      
      	sunxi_led_enable_irq(led);
      
      	return 0;
      }
      
      static const struct dev_pm_ops sunxi_led_pm_ops = {
      	.suspend = sunxi_led_suspend,
      	.resume = sunxi_led_resume,
      };
      
      #define SUNXI_LED_PM_OPS (&sunxi_led_pm_ops)
      #endif
      
      static const struct of_device_id sunxi_led_dt_ids[] = {
      	{.compatible = "allwinner,sunxi-leds"},
      	{},
      };
      
      static struct platform_driver sunxi_led_driver = {
      	.probe		= sunxi_led_probe,
      	.remove		= sunxi_led_remove,
      	.driver		= {
      		.name	= "sunxi-leds",
      		.owner	= THIS_MODULE,
      #if IS_ENABLED(CONFIG_PM)
      		.pm	= SUNXI_LED_PM_OPS,
      #endif
      		.of_match_table = sunxi_led_dt_ids,
      	},
      };
      
      module_platform_driver(sunxi_led_driver);
      module_param_named(debug, debug_mask, int, 0664);
      
      MODULE_ALIAS("sunxi leds dirver");
      MODULE_ALIAS("platform : leds dirver");
      MODULE_LICENSE("GPL v2");
      MODULE_VERSION("1.2.3");
      MODULE_AUTHOR("Albert Yu <yuxyun@allwinnertech.com>");
      MODULE_AUTHOR("liuyu <SWCliuyus@allwinnertech.com>");
      MODULE_DESCRIPTION("Allwinner ledc-controller driver");
      

      请更新 leds-sunxi.c 修复了 LEDC DMA相关功能

      发布在 MR Series
      A
      awwwwa
    • 回复: R128 GPIO默认功能和复用说明在哪里可以查?

      https://r128.docs.aw-ol.com/r128/chip_info/#gpio

      发布在 A Series
      A
      awwwwa
    • 回复: V851S I2C/TWI 损坏(xfer 错误)

      @kanken6174 上拉是1.8V吗,还是上拉到3.3v了

      发布在 V Series
      A
      awwwwa
    • 回复: T113-S3芯片使用Tina5.0,开机小企鹅boot能显示但跳转到kernel后无显示

      @pandali 检查LCD的rst引脚是否配置错误导致屏幕被rst

      发布在 Linux
      A
      awwwwa
    • 回复: D1s ledc驱动代码bug,DMA模式无法使用

      @leomini5 我这边没有D1s的板卡,在T113上测试通过,测试1024颗灯,这个可能是RV才有的bug?

      发布在 MR Series
      A
      awwwwa
    • 回复: R128S2 Ubuntu20.04 编译系统错误

      @oneofzero 删除这两个文件可以用吗

      发布在 A Series
      A
      awwwwa
    • 回复: V853 SDK : PMU TWI

      @alb702 在 V853 SDK : PMU TWI 中说:

      [267]ic cant match axp, please check...

      V853 和 V853s 的芯片安全系统验证不一样,SDK不能通用,这行输出表示芯片型号验证失败,跳过初始化DRAM

      发布在 V Series
      A
      awwwwa
    • 回复: tina SDK ERROR: Dependence broken. Firmware maybe incorrect & cannot booting up...

      @hgs1975 This is not a error, you can normal boot up while showing this error. What's your hardware and how to configure it

      发布在 Linux
      A
      awwwwa
    • 回复: Tina-T113 openWrt 新增软件包,选中menuconfig后,编译报错,makefile完全就是按照sdk里QT对应的makefile来写的

      Makefile:68: *** missing separator. Stop.

      这个错误通常表示在 Makefile 的第 68 行或附近存在语法错误。Makefile 中使用的规则必须遵循严格的缩进规范,通常是使用 Tab 键进行缩进,而不是空格。

      请检查 Makefile 第 68 行附近的代码,确保每个规则的命令部分都以 Tab 键开头,并且规则名称和命令之间使用冒号(:)分隔。此外,还需要确认 Makefile 的每一行都是使用相同的缩进方式,要么都是 Tab,要么都是空格,不要混用。

      发布在 MR Series
      A
      awwwwa
    • 回复: R128 SDK。运行lunch_rtos退出的时候报错。

      @tianya000180 v0.9版本R128 SDK已修复,不是报错只是使用错误可以无视

      发布在 A Series
      A
      awwwwa
    • 回复: 测试编译不过

      打入这个补丁试一下:de88083d-a6c8-403e-947c-81ccd05dc849-0001-fix-add-ENABLE_HARDFP-options.patch

      0001-feat-Support-e907-core-boot-up.patch

      可能是不同编译器导致的

      发布在 V Series
      A
      awwwwa
    • 回复: 只用的全志的板子,怎么才能往rootfs中添加文件

      target/allwinner/t113-nezha/base-files
      target/allwinner/t113-nezha/busybox-init-base-files

      根据选择的overlay方式而定

      发布在 Linux
      A
      awwwwa
    • 回复: D1-H哪吒开发板HDMI默认可以使用吗

      默认HDMI不开,需要命令开启

      cd /sys/kernel/debug/dispdbg
      echo disp0 > name; echo switch1 > command; echo 4 10 0 0 0x4 0x101 0 0 0 8 > param; echo 1 > start;
      
      发布在 MR Series
      A
      awwwwa
    • 回复: LVGL 与 SPI TFT GUI案例报错

      https://r128.docs.aw-ol.com/others/faq/#_3

      建议 删除 PMU 相关配置

      [pmu]
      pmu_irq_pin      = port:PA14<14><0><default><default>
      pmu_irq_wakeup   = 2
      pmu_hot_shutdown = 1
      pmu_bat_unused = 0
      pmu_usbad_vol = 4600
      pmu_usbad_cur = 1500
      pmu_usbpc_vol = 4600
      pmu_usbpc_cur = 500
      pmu_chg_ic_temp = 0
      pmu_battery_rdc = 100
      pmu_battery_cap = 3568
      pmu_runtime_chgcur = 900
      pmu_suspend_chgcur = 1200
      pmu_shutdown_chgcur = 1200
      pmu_init_chgvol = 4200
      pmu_init_chg_pretime = 50
      pmu_init_chg_csttime = 1200
      pmu_chgled_type = 0
      pmu_init_bc_en = 1
      pmu_bat_temp_enable = 0
      pmu_bat_charge_ltf = 2261
      pmu_bat_charge_htf = 388
      pmu_bat_shutdown_ltf = 3200
      pmu_bat_shutdown_htf = 237
      pmu_bat_para[0] = 0
      pmu_bat_para[1] = 0
      pmu_bat_para[2] = 0
      pmu_bat_para[3] = 0
      pmu_bat_para[4] = 0
      pmu_bat_para[5] = 0
      pmu_bat_para[6] = 1
      pmu_bat_para[7] = 1
      pmu_bat_para[8] = 2
      pmu_bat_para[9] = 4
      pmu_bat_para[10] = 5
      pmu_bat_para[11] = 12
      pmu_bat_para[12] = 19
      pmu_bat_para[13] = 32
      pmu_bat_para[14] = 41
      pmu_bat_para[15] = 45
      pmu_bat_para[16] = 48
      pmu_bat_para[17] = 51
      pmu_bat_para[18] = 54
      pmu_bat_para[19] = 59
      pmu_bat_para[20] = 63
      pmu_bat_para[21] = 68
      pmu_bat_para[22] = 71
      pmu_bat_para[23] = 74
      pmu_bat_para[24] = 78
      pmu_bat_para[25] = 81
      pmu_bat_para[26] = 82
      pmu_bat_para[27] = 84
      pmu_bat_para[28] = 88
      pmu_bat_para[29] = 92
      pmu_bat_para[30] = 96
      pmu_bat_para[31] = 100
      pmu_bat_temp_para[0] = 7466
      pmu_bat_temp_para[1] = 4480
      pmu_bat_temp_para[2] = 3518
      pmu_bat_temp_para[3] = 2786
      pmu_bat_temp_para[4] = 2223
      pmu_bat_temp_para[5] = 1788
      pmu_bat_temp_para[6] = 1448
      pmu_bat_temp_para[7] = 969
      pmu_bat_temp_para[8] = 664
      pmu_bat_temp_para[9] = 466
      pmu_bat_temp_para[10] = 393
      pmu_bat_temp_para[11] = 333
      pmu_bat_temp_para[12] = 283
      pmu_bat_temp_para[13] = 242
      pmu_bat_temp_para[14] = 179
      pmu_bat_temp_para[15] = 134
      
      发布在 A Series
      A
      awwwwa
    • 回复: 测试编译不过
      • helloworld_fel 使用了 VFP 寄存器参数,但是某个库文件(libgcc.a(_udivmoddi4.o))却不支持。

      • 缺少 .note.GNU-stack 段,暗示可执行栈缺失。

      • 对于具有 RWX 权限的 LOAD 段,给出了警告。

      • 在链接时,出现了对 raise 函数的未定义引用。

      发布在 V Series
      A
      awwwwa
    • 回复: 请问docker pull registry.cn-hangzhou.aliyuncs.com/cld1994/tina-sdk:5.0-nori拉取docker镜像没有问题,配置后,运行code ~/workspace/nori进入vscode,Reopen in Container却报错是为什么呢

      docker 没有正确安装配置

      发布在 Linux
      A
      awwwwa
    • 回复: ubuntu使用scp传文件给Tina 2.0 SDK

      默认没有密码,加密码需要配置下

      发布在 MR Series
      A
      awwwwa
    • 回复: R128 Vector支持

      请贴出编译日志。

      发布在 A Series
      A
      awwwwa
    • 回复: v853 vin通路配置

      (1)在线模式:四个vipp和dma实体,最大缩小比例为16*16,每路最多可支持16个orl
      (2)离线模式:每个vipp和dma可分时复用为4个vipp和dma虚拟体,四个vipp和dma实体相互独立,在线模式和离线模式开关也是相互独立的;
      (3)VIPP和DAM的分时复用(离线模式)与isp和tdm的分时复用(离线模式)是绑定关系,即tdm和isp开启了离线模式,vipp和dma的输入端如果是isp,那么vipp和dma也需要开启离线模式;
      (4)只有VIPP0和dma0实体支持VE在线编码,而vipp0在线,如果vipp00的输入端为isp,那么tdm和isp也只能配置在线模式,而isp在线,那么四个vipp和dma实体都只能配置在线模式;

      online 和 offline 配 置 方 式 在 board.dts , 所 以 需 要 在 对 应 版 型 的 board.dts 中 找 到 vind0 节 点 配 置 列 表 , 对 应 关 系 为 tdm 对 应 节 点 , isp 对 应 isp00 节 点 , vipp 对 应 scaler00 、 scaler10 、 scaler20 和 scaler30 节 点 , dma 对 , 应 vinc00 、 vinc10 、 vinc20 和 vinc30 节 点 。

      • 在线模式,单路3输出

      18ca36be-ad38-4813-9032-065baa08e803-image.png

      • 离线模式,2路8输出

      7c83156e-caa3-4a20-b0cb-cbb1546d1931-image.png

      发布在 V Series
      A
      awwwwa
    • 回复: t113-s3 lvgl仪表盘指针转动如何处理

      旋转需要大量的计算,会导致出现帧率问题,可以尝试关闭抗锯齿,使用NEON加速计算

      发布在 Linux
      A
      awwwwa
    • 回复: 哪吒D1-H 通过bootargs来静态设置ip

      OpenWRT会重写kernel部分的配置,具体请参考OpenWRT文档

      发布在 MR Series
      A
      awwwwa
    • 回复: 求助 r128 dsp

      RI-2020.5-linux 编译器需要向购买开发板的商家/代理提交申请,需要提供自己的HIFI5 DSP Xtensa Xplorer的证明

      发布在 A Series
      A
      awwwwa
    • 回复: 关于打印启动日志到/dev/fb0的问题

      找到 env.cfg

      
      #kernel command arguments
      earlyprintk=sunxi-uart,0x02500000
      initcall_debug=0
      console=ttyS0,115200
      consolefb=tty0
      nand_root=ubi0_4
      mmc_root=/dev/mmcblk0p4
      nor_root=/dev/mtdblock1
      init=/init
      loglevel=8
      coherent_pool=16K
      #reserve_list=30M@64M,78M@128M,200M@512M
      mac=
      wifi_mac=
      bt_mac=
      specialstr=
      root_partition=rootfs
      mtd_name=sys
      rootfstype=ubifs, rw
      #set kernel cmdline if boot.img or recovery.img has no cmdline we will use this
      setargs_nor=setenv bootargs  earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} console=${console—fb} loglevel=${loglevel} root=${nor_root} rootwait init=${init} rdinit=${rdinit} partitions=${partitions} cma=${cma} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      setargs_nand=setenv bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} console=${console—fb} loglevel=${loglevel}  ubi.mtd=${mtd_name} root=${nand_root} rootfstype=${rootfstype} rootwait init=${init} rdinit=${rdinit} partitions=${partitions} cma=${cma} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      setargs_nand_ubi=setenv bootargs ubi.mtd=${mtd_name} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} console=${console—fb} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
      setargs_mmc=setenv  bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} console=${console—fb} loglevel=${loglevel} root=${mmc_root}  rootwait init=${init} partitions=${partitions} cma=${cma} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} coherent_pool=${coherent_pool} ion_carveout_list=${reserve_list}
      #nand command syntax: sunxi_flash read address partition_name read_bytes
      #0x4007f800 = 0x40080000(kernel entry) - 0x800(boot.img header 2k)
      boot_partition=boot
      boot_normal=sunxi_flash read 44800000 ${boot_partition};bootm 44800000
      boot_recovery=sunxi_flash read 44800000 extend;bootm 44800000
      boot_fastboot=fastboot
      #recovery key
      recovery_key_value_max=0x13
      recovery_key_value_min=0x10
      #fastboot key
      fastboot_key_value_max=0x8
      fastboot_key_value_min=0x2
      
      #uboot system env config
      bootdelay=1
      #default bootcmd, will change at runtime according to key press
      bootcmd=run setargs_nand boot_normal#default nand boot
      #verify the kernel
      verify=N
      
      
      发布在 V Series
      A
      awwwwa
    • 回复: T113基于Longan在LVGL中如何播放视屏,通过tplayer
          static lv_style_t style_scr_act;
          if (style_scr_act.prop_cnt == 0) {
              lv_style_init(&style_scr_act);
              lv_style_set_bg_opa(&style_scr_act, LV_OPA_COVER);
              lv_obj_add_style(lv_scr_act(), &style_scr_act, 0);
          }
          lv_disp_get_default()->driver->screen_transp = 1;
          lv_disp_set_bg_opa(lv_disp_get_default(), LV_OPA_TRANSP);
          /* Empty the buffer, not emptying will cause the UI to be opaque */
          lv_memset_00(lv_disp_get_default()->driver->draw_buf->buf_act,
          lv_disp_get_default()->driver->draw_buf->size * sizeof(lv_color32_t));
          lv_style_set_bg_opa(&style_scr_act, LV_OPA_TRANSP);
          lv_obj_report_style_change(&style_scr_act);
      

      设置透明层

      发布在 GUI
      A
      awwwwa
    • 回复: R128S2 SDK 编译错误

      @yilan7805 看上去解压工具链压缩文件有损坏,重新下载一下?

      发布在 MR Series
      A
      awwwwa
    • 回复: 关于Linux环境下R128的烧录环境

      @l1878980638

      a491662e-ed17-436f-80d8-c316e36c4815-image.png

      https://www.aw-ol.com/downloads?cat=5

      发布在 A Series
      A
      awwwwa
    • 1
    • 2
    • 1 / 2