@zifeiyu uboot阶段fdt print看看有没有okay,另外图没发上来
awwwwa 发布的帖子
-
回复: 修改了linux-5.4/board.dts的uart0部分,但是烧写到板子上面没有生效
-
回复: v851 使用sample_rtsp 报ISP_ERR
检查使用的SDK是哪一个版本,目前awol的Tina 5.0不支持sample_rtsp,这个demo适配的是Tina 4.0,需要向代理获取支持
-
回复: tina linux SDL1.2.15
@wj8331585 支持,出现段错误可以编译一个gdb进去看看哪里错了
测试代码:
w = 1920; h = 1080; bpp = 32; SDL_Init( SDL_INIT_EVERYTHING ); SDL_SetVideoMode( w,h, bpp, SDL_HWSURFACE|SDL_DOUBLEBUF );
-
回复: V853SDK:奇怪的帧缓冲区操作
@alb702 add your layer and cat that file see what layer you configured
-
回复: R128 WIFI AP模式获取连接设备的IP地址的问题
AP的数据是在 lwip 的 static struct etharp_entry arp_table[ARP_TABLE_SIZE]; 中维护
#if LWIP_XR_IMPL ip4_addr_t* etharp_get_ip_from_mac(struct eth_addr *ethaddr) { int i; ip4_addr_t* ip_ret = NULL; LWIP_ASSERT("ethaddr != NULL", ethaddr != NULL); for (i = 0; i < ARP_TABLE_SIZE; i++) { if (memcmp(ethaddr, &arp_table[i].ethaddr, sizeof(struct eth_addr)) == 0) { ip_ret = &arp_table[i].ipaddr; break; } } return ip_ret; } #endif
-
回复: V853SDK:奇怪的帧缓冲区操作
@alb702 try to
cat /sys/class/disp/disp/attr/sys
empty:
root@TinaLinux:/# cat /sys/class/disp/disp/attr/sys screen 0: de_rate 300000000 hz, ref_fps:62 mgr0: 800x1280 fmt[rgb] cs[0x204] range[full] eotf[0x4] bits[8bits] err[0] force_sync[0] unblank direct_show[false] iommu[1] dmabuf: cache[0] cache max[0] umap skip[0] umap skip max[52] lcd output backlight(100) fps:62.1 800x1280 err:0 skip:228 irq:2786 vsync:0 vsync_skip:0 BUF enable ch[1] lyr[0] z[16] prem[N] a[pixel 255] fmt[ 0] fb[ 800,1280; 800,1280; 800,1280] crop[ 0, 0, 800,1280] frame[ 0, 0, 800,1280] addr[ff800000, 0, 0] flags[0x 0] trd[0,0] depth[ 0]
add layer
cat /sys/class/disp/disp/attr/sys screen 0: de_rate 300000000 hz, ref_fps:62 mgr0: 800x1280 fmt[rgb] cs[0x204] range[full] eotf[0x4] bits[8bits] err[0] force_sync[0] unblank direct_show[false] iommu[1] dmabuf: cache[0] cache max[0] umap skip[0] umap skip max[52] lcd output backlight(100) fps:62.1 800x1280 err:933 skip:228 irq:6815 vsync:0 vsync_skip:0 COLOR enable ch[0] lyr[0] z[16] prem[N] a[pixel 0] fmt[ 0] fb[ 0, 0; 0, 0; 0, 0] crop[ 0, 0, 200,1280] frame[ 0, 0, 200,1280] addr[ffff0000, 0, 0] flags[0x 0] trd[0,0] depth[ 0] COLOR enable ch[0] lyr[1] z[16] prem[N] a[pixel 0] fmt[ 0] fb[ 0, 0; 0, 0; 0, 0] crop[ 200, 0, 200,1280] frame[ 200, 0, 200,1280] addr[ff00ff00, 0, 0] flags[0x 0] trd[0,0] depth[ 0] COLOR enable ch[0] lyr[2] z[16] prem[N] a[pixel 0] fmt[ 0] fb[ 0, 0; 0, 0; 0, 0] crop[ 400, 0, 200,1280] frame[ 400, 0, 200,1280] addr[ff0000ff, 0, 0] flags[0x 0] trd[0,0] depth[ 0] COLOR enable ch[0] lyr[3] z[16] prem[N] a[pixel 0] fmt[ 0] fb[ 0, 0; 0, 0; 0, 0] crop[ 600, 0, 200,1280] frame[ 600, 0, 200,1280] addr[ffffff00, 0, 0] flags[0x 0] trd[0,0] depth[ 0] BUF enable ch[1] lyr[0] z[16] prem[N] a[pixel 255] fmt[ 0] fb[ 800,1280; 800,1280; 800,1280] crop[ 0, 0, 800,1280] frame[ 0, 0, 800,1280] addr[ff800000, 0, 0] flags[0x 0] trd[0,0] depth[ 0]
-
回复: 全H616启动,GPIO和eFuse启动选择,是在哪里设置的
@fleieng 如果烧录了eFuse会写eFuse标志位,就是eFuse选择,如果没烧eFuse,则是GPIO选择,芯片出厂默认是GPIO选择
-
回复: V853SDK:奇怪的帧缓冲区操作
try to use english to describe, the translate I can't understand.
-
回复: T113-S3解码1080P视频花屏,set scaledown视频画面不动
package/allwinner/tina_multimedia/tplayer/configs/t113_linux_cedarx.conf
检查是否使用
video lbc mode, is_lossy and rc_en
如果配置了设置 0 0 0
########### paramter ############ [paramter] start_play_cache_video_frame_num = 4 start_play_cache_size = 8 # KB cache_buffer_size = 10240 # KB cache_buffer_size_live = 10240 # KB start_play_cache_time = 5 # Second max_start_play_chache_size = 512 # KB max_cache_buffer_size = 10240 # KB max_http_stream_buf_size = 2048 #KB # the number of audio stream cached before decoding. max_audio_stream_frame_num = 128 # see comment in player.cpp av_sync_duration = 0 # millisecond # picture num for modules pic_4list_num = 2 pic_4di_num = 0 pic_4rotate_num = 0 pic_4smooth_num = 2 # picture format: mb32/nv21/nv12/nv # deinterlace format deinterlace_fmt = nv12 # video decoder output picture format vd_output_fmt = nv21 # video lbc mode, is_lossy and rc_en vd_lbc_mode = 2 vd_lbc_is_lossy = 1 vd_lbc_rc_en = 0 # gpu align stride values: 16/32 # mali 400mp2 32bit gpu_align_bitwidth = 32 # if value 1 : send 3-frames black-pic to GPU # SP: switch Program #black_pic_4_SP = 0 # compensate for av vsync compensate_vsync = 4 #use transform module to rotate the video. notice:only r18/r58/r40 support transform module tr_rotate_flag = 0 #1 means rotate,0 means not rotate tr_rotate_degree = 0 #0 means the degree is 0, 90 means the degree is 90,180 means the degree is 180, 270 means the degree is 270 #use g2d module to rotate the video. notice:F133/R528 g2d_rotate_degree = 0 #the max width and height of video in this product,which need align 64 hold_last_picture_with = 1920 hold_last_picture_height = 1088 #The first frame decoded will be used for quick display. show_1th_frame_quick = 1 # log will output if level >= log_level #VERBOSE = 2, #DEBUG = 3, #INFO = 4, #WARNING = 5, #ERROR = 6, log_level = 6 # define platform for ve phy addr offset platform = t113 # scaledown large video(>=1080p) or not,0:means not scaledown,1:means scaledown scaledown_large_video_flag = 0 #use ion buf in streamManager.c , 0:means not use ion buf,1:means use ion buf use_ion_buf_flag = 0 ########### plugin ############## # 1. audio decoder plugin [adecoder-0] comment = aac_adecoder id = adecoder.aac lib = libaw_aacdec.so [adecoder-1] comment = alac_adecoder id = adecoder.alac lib = libaw_alacdec.so [adecoder-2] comment = amr_adecoder id = adecoder.amr lib = libaw_amrdec.so [adecoder-3] comment = ape_adecoder id = adecoder.ape lib = libaw_apedec.so [adecoder-4] comment = flac_adecoder id = adecoder.flac lib = libaw_flacdec.so [adecoder-5] comment = mp3_adecoder id = adecoder.mp3 lib = libaw_mp3dec.so [adecoder-6] comment = ogg_adecoder id = adecoder.ogg lib = libaw_oggdec.so [adecoder-7] comment = wav_adecoder id = adecoder.wav lib = libaw_wavdec.so [adecoder-8] comment = atrc_adecoder id = adecoder.atrc lib = libaw_atrcdec.so [adecoder-9] comment = ra_adecoder id = adecoder.ra lib = libaw_radec.so [adecoder-10] comment = dsd_adecoder id = adecoder.dsd lib = libaw_dsddec.so [adecoder-11] comment = g729_adecoder id = adecoder.g729 lib = libaw_g729dec.so [adecoder-12] comment = opus_adecoder id = adecoder.opus lib = libaw_opusdec.so # 2. video decoder plugin [vdecoder-0] comment = h264_vdecoder id = vdecoder.h264 lib = libawh264.so init = CedarPluginVDInit [vdecoder-1] comment = mjpeg_vdecoder id = vdecoder.mjpeg lib = libawmjpeg.so init = CedarPluginVDInit [vdecoder-2] comment = mpeg2_vdecoder id = vdecoder.mpeg2 lib = libawmpeg2.so init = CedarPluginVDInit [vdecoder-3] comment = mpeg4base_vdecoder id = vdecoder.mpeg4base lib = libawmpeg4base.so init = CedarPluginVDInit [vdecoder-4] comment = mpeg4dx_vdecoder id = vdecoder.mpeg4dx lib = libawmpeg4dx.so init = CedarPluginVDInit reference = vdecoder.mpeg4base [vdecoder-5] comment = mpeg4h263_vdecoder id = vdecoder.mpeg4h263 lib = libawmpeg4h263.so init = CedarPluginVDInit reference = vdecoder.mpeg4base [vdecoder-6] comment = mpeg4normal_vdecoder id = vdecoder.mpeg4normal lib = libawmpeg4normal.so init = CedarPluginVDInit reference = vdecoder.mpeg4base [vdecoder-7] comment = wmv3_vdecoder id = vdecoder.wmv3 lib = libawwmv3.so init = CedarPluginVDInit [vdecoder-8] comment = h265_vdecoder id = vdecoder.h265 lib = libawh265.so init = CedarPluginVDInit # 3. external plugin #[plugin-0] #comment = rtp_plugin #id = rtp #lib = librtp.so
-
回复: T113pro使用tina sdk无法将模块自动拷进rootfs
检查一下modules的配置
define KernelPackage/net-broadcom SUBMENU:=$(WIRELESS_MENU) DEPENDS:= +ap6256-firmware +@PACKAGE_broadcom-rftest TITLE:=broadcom(ap6256...) support FILES:=$(LINUX_DIR)/drivers/net/wireless/bcmdhd/bcmdhd.ko KCONFIG:=\ CONFIG_BCMDHD=m \ CONFIG_BCMDHD_SDIO=y \ CONFIG_BCMDHD_OOB=y \ CONFIG_BCMDHD_FW_PATH="/etc/firmware/fw_bcmdhd.bin" \ CONFIG_BCMDHD_NVRAM_PATH="/etc/firmware/nvram.txt" \ CONFIG_BCMDHD_SDIO=y \ CONFIG_SUNXI_RFKILL=y \ CONFIG_MMC=y \ CONFIG_PWRSEQ_EMMC=y \ CONFIG_PWRSEQ_SIMPLE=y \ CONFIG_MMC_SUNXI=y \ CONFIG_MMC_SUNXI_V4P1X=y \ CONFIG_MMC_SUNXI_V4P00X=y \ CONFIG_MMC_SUNXI_V4P10X=y \ CONFIG_MMC_SUNXI_V4P5X=y \ CONFIG_MMC_SUNXI_V5P3X=y \ AUTOLOAD:=$(call AutoProbe,bcmdhd,1) endef define KernelPackage/net-broadcom/description Kernel modules for Broadcom AP6256... support endef $(eval $(call KernelPackage,net-broadcom))
-
回复: D1s DMA驱动Ledc 问题
使用dma模式搬运数据,需要打上如下补丁:
ledc在dma模式的代码存在问题,已修复该问题,ledc的dma通道之前也没有支持,需要添加上
diff --git a/hal/source/dma/platform/dma-sun8iw20.h b/hal/source/dma/platform/dma-sun8iw20.h index 2140014..fc5c72e 100644 --- a/hal/source/dma/platform/dma-sun8iw20.h +++ b/hal/source/dma/platform/dma-sun8iw20.h @@ -136,6 +136,7 @@ #define DRQDST_OTG_EP3 32 #define DRQDST_OTG_EP4 33 #define DRQDST_OTG_EP5 34 +#define DRQDST_LEDC 42 #define DRQDST_TWI0_TX 43 #define DRQDST_TWI1_TX 44 #define DRQDST_TWI2_TX 45 diff --git a/hal/source/ledc/hal_ledc.c b/hal/source/ledc/hal_ledc.c index 5499452..ddf471f 100755 --- a/hal/source/ledc/hal_ledc.c +++ b/hal/source/ledc/hal_ledc.c @@ -20,9 +20,10 @@ #define led_err(fmt, args...) printf("%s()%d - "fmt, __func__, __LINE__, ##args) #define LEDC_PIN_SLEEP 0 +#define LEDC_DMA_BUF_SIZE 4096 struct ledc_config ledc_config = { - .led_count = 3, + .led_count = 1024, .reset_ns = 84, .t1h_ns = 800, .t1l_ns = 450, @@ -37,6 +38,7 @@ static unsigned long base_addr = LEDC_BASE; struct sunxi_dma_chan *dma_chan; struct sunxi_led *led; +static uint8_t already_init; static hal_irqreturn_t sunxi_ledc_irq_handler(void *dummy) { @@ -448,15 +450,16 @@ void hal_ledc_dma_callback(void *para) { - printf("dma callback\n"); + ledc_info("dma transfer end\n"); } -void hal_ledc_trans_data(struct ledc_config *ledc) +int hal_ledc_trans_data(struct ledc_config *ledc) { - int i; + int i, ret; unsigned long int size; unsigned int mask = 0; struct dma_slave_config slave_config; + unsigned int const *buf = ledc->data; mask = LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN; @@ -480,23 +483,32 @@ ledc_reset_en(); size = ledc->length * 4; + if (size <= LEDC_DMA_BUF_SIZE) { + memcpy(ledc->align_dma_buf, buf, ledc->length); + buf = ledc->align_dma_buf; + } - hal_dcache_clean((unsigned long)ledc->data, sizeof(ledc->data)); + hal_dcache_clean((unsigned long)buf, size); slave_config.direction = DMA_MEM_TO_DEV; - slave_config.src_addr = (unsigned long)(ledc->data); + slave_config.src_addr = (unsigned long)buf; slave_config.dst_addr = (uint32_t)(base_addr + LEDC_DATA_REG); slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - slave_config.src_maxburst = DMA_SLAVE_BURST_16; - slave_config.dst_maxburst = DMA_SLAVE_BURST_16; + slave_config.src_maxburst = DMA_SLAVE_BURST_4; + slave_config.dst_maxburst = DMA_SLAVE_BURST_4; slave_config.slave_id = sunxi_slave_id(DRQDST_LEDC, DRQSRC_SDRAM); - hal_dma_slave_config(dma_chan, &slave_config); + ret = hal_dma_slave_config(dma_chan, &slave_config); + if (ret) { + led_err("dma slave config failed\n"); + return -1; + } - hal_dma_prep_device(dma_chan, slave_config.dst_addr, slave_config.src_addr, size, DMA_MEM_TO_DEV); - - //dma_chan->callback = ledc_dma_callback; - hal_dma_start(dma_chan); + ret = hal_dma_prep_device(dma_chan, slave_config.dst_addr, slave_config.src_addr, size, DMA_MEM_TO_DEV); + if (ret) { + led_err("dma prep device failed\n"); + return -1; + } hal_ledc_set_time(ledc); ledc_set_output_mode(ledc->output_mode); @@ -504,7 +516,15 @@ ledc_set_dma_mode(); ledc_enable_irq(mask); ledc_enable(); + + dma_chan->callback = hal_ledc_dma_callback; + ret = hal_dma_start(dma_chan); + if (ret) { + led_err("dma start trans failed\n"); + return -1; + } } + return 0; } void hal_ledc_clear_all_irq(void) @@ -598,6 +618,14 @@ int hal_ledc_init(void) { + if (already_init) { + already_init++; + ledc_info("ledc has been inited, return ok\n"); + return 0; + } + + int ret, i; + ledc_info("hal_led_init\n"); led = malloc(sizeof(struct sunxi_led)); @@ -611,25 +639,40 @@ led->config.data = malloc(sizeof(unsigned int) * led->config.led_count); if (NULL == led->config.data) { led_err("sunxi led config data malloc err\n"); - goto err1; + goto err0; } + for(i = 0;i < led->config.led_count;i++) + led->config.data[i] = 0; if (ledc_clk_init()) { led_err("ledc clk init failed \n"); + goto err1; } if (ledc_pinctrl_init()) { led_err("ledc pinctrl init failed \n"); + goto err2; } - hal_dma_chan_request(&dma_chan); + ret = hal_dma_chan_request(&dma_chan); + if (ret == HAL_DMA_CHAN_STATUS_BUSY) + { + led_err("request dma_chan failed\n"); + goto err3; + } + led->config.align_dma_buf = dma_alloc_coherent(LEDC_DMA_BUF_SIZE); + if (!led->config.align_dma_buf) + { + led_err("alloc dma memory failed\n"); + goto err4; + } if (hal_request_irq(SUNXI_IRQ_LEDC, sunxi_ledc_irq_handler, "ledc", led) < 0) { led_err("ledc request irq failed \n"); - goto errirq; + goto err5; } hal_enable_irq(SUNXI_IRQ_LEDC); @@ -638,13 +681,22 @@ pm_devops_register(&pm_ledc); #endif + already_init++; ledc_info("hal_led_init success\n"); return 0; -errirq: - free(led->config.data); +err5: + dma_free_coherent(led->config.align_dma_buf); +err4: + hal_dma_chan_free(dma_chan); +err3: + ledc_pinctrl_exit(); +err2: + ledc_clk_exit(); err1: + free(led->config.data); +err0: free(led); return -1; @@ -652,27 +704,35 @@ void hal_ledc_deinit(void) { + if (already_init > 0) { + if (--already_init == 0) { #ifdef CONFIG_COMPONENTS_PM - pm_devops_unregister(&pm_ledc); + pm_devops_unregister(&pm_ledc); #endif - hal_disable_irq(SUNXI_IRQ_LEDC); - hal_free_irq(SUNXI_IRQ_LEDC); - hal_dma_chan_free(dma_chan); - ledc_pinctrl_exit(); - ledc_clk_exit(); - free(led->config.data); - free(led); + hal_disable_irq(SUNXI_IRQ_LEDC); + hal_free_irq(SUNXI_IRQ_LEDC); + dma_free_coherent(led->config.align_dma_buf); + hal_dma_chan_free(dma_chan); + ledc_pinctrl_exit(); + ledc_clk_exit(); + free(led->config.data); + free(led); + } + } } int sunxi_set_all_led(unsigned int brightness) { - int i; + int i, ret; led->config.length = led->config.led_count; for(i = 0;i < led->config.led_count;i++) led->config.data[i] = brightness; - hal_ledc_trans_data(&led->config); + ret = hal_ledc_trans_data(&led->config); + if (ret) { + led_err("ledc trans data error\n"); + } return 0; } @@ -680,6 +740,7 @@ int sunxi_set_led_brightness(int led_num, unsigned int brightness) { u32 reg_val; + int i, ret; if (NULL == led) { led_err("err : ledc is not init\n"); @@ -691,10 +752,16 @@ return -1; } - led->config.length = 1; + led->config.length = led_num; led->config.data[led_num-1] = brightness; - hal_ledc_trans_data(&led->config); + for (i = 0; i < led_num; i++) + ledc_info("the %d led light is %u\n", i + 1, led->config.data[i]); + + ret = hal_ledc_trans_data(&led->config); + if (ret) { + led_err("ledc trans data error\n"); + } reg_val = hal_ledc_get_irq_status(); ledc_info("ledc interrupt status reg is %x", reg_val); diff --git a/hal/source/ledc/platform_ledc.h b/hal/source/ledc/platform_ledc.h index 39f6933..2fa9c38 100644 --- a/hal/source/ledc/platform_ledc.h +++ b/hal/source/ledc/platform_ledc.h @@ -33,8 +33,6 @@ #ifndef __PLATFORM_LEDC_H__ #define __PLATFORM_LEDC_H__ -#define DRQDST_LEDC 43 - #if defined(CONFIG_ARCH_SUN8IW18P1) #include "platform/ledc_sun8iw18.h" #endif diff --git a/hal/test/ledc/test_ledc.c b/hal/test/ledc/test_ledc.c index 1ade796..79694c0 100755 --- a/hal/test/ledc/test_ledc.c +++ b/hal/test/ledc/test_ledc.c @@ -20,6 +20,7 @@ int ledc_test(int argc, char **argv) { int brightness = 0; + int led_num; printf("========LEDC TEST========\n"); @@ -32,9 +33,14 @@ return 0; } - brightness = atoi(argv[2]); + led_num = atoi(argv[1]); + if (led_num < 1 || led_num > 1024) + { + printf("The led_num you entered should be between 1 and 1024\n"); + } + brightness = atoi(argv[3]); - switch(argv[1][0]) + switch(argv[2][0]) { case 'R' : brightness <<= 8; break; case 'G' : brightness <<= 16; break; @@ -43,7 +49,8 @@ return -1; } - sunxi_set_led_brightness(1, brightness); + sunxi_set_led_brightness(led_num, brightness); + printf("led is %d\n", led_num); printf("brightness is %d\n", brightness); return 0; diff --git a/include/hal/sunxi_hal_ledc.h b/include/hal/sunxi_hal_ledc.h index a386338..e5a70d1 100644 --- a/include/hal/sunxi_hal_ledc.h +++ b/include/hal/sunxi_hal_ledc.h @@ -43,6 +43,7 @@ unsigned long long wait_time1_ns; unsigned int wait_data_time_ns; char *output_mode; + unsigned int *align_dma_buf; unsigned int *data; unsigned int length; }; @@ -86,7 +87,7 @@ int hal_ledc_init(void); void hal_ledc_deinit(void); -void hal_ledc_trans_data(struct ledc_config *ledc); +int hal_ledc_trans_data(struct ledc_config *ledc); void hal_ledc_clear_all_irq(void); unsigned int hal_ledc_get_irq_status(void); void hal_ledc_dma_callback(void *para);
DMA下 LED 颜色异常
diff --git a/hal/source/ledc/hal_ledc.c b/hal/source/ledc/hal_ledc.c index ddf471f4..8d818662 100755 --- a/hal/source/ledc/hal_ledc.c +++ b/hal/source/ledc/hal_ledc.c @@ -308,11 +308,15 @@ static void ledc_set_wait_data_time_ns(unsigned int wait_data_time_ns) hal_writel(reg_val, base_addr + LEDC_DATA_FINISH_CNT_REG); } +/* + * set the num of leds on the led-strip + * max support up to 1024 leds + */ static void ledc_set_length(unsigned int length) { unsigned int reg_val; - if (length == 0) + if (length == 0 || length > 1024) return; reg_val = hal_readl(base_addr + LEDC_CTRL_REG); @@ -721,12 +725,22 @@ void hal_ledc_deinit(void) } } -int sunxi_set_all_led(unsigned int brightness) +/* + * set the brightness of all the leds in led-strip to a uniform value + * @length: the num of leds on led-strip + * @brightness: the brightness data + */ +int sunxi_set_all_led(unsigned int length, unsigned int brightness) { int i, ret; - led->config.length = led->config.led_count; - for(i = 0;i < led->config.led_count;i++) + if (length > led->config.led_count) { + led_err("%d: max support 1024 leds\n", length); + return -1; + } + + led->config.length = length; + for(i = 0;i < led->length;i++) led->config.data[i] = brightness; ret = hal_ledc_trans_data(&led->config); @@ -737,7 +751,13 @@ int sunxi_set_all_led(unsigned int brightness) return 0; } -int sunxi_set_led_brightness(int led_num, unsigned int brightness) +/* + * set the brightness of each led on the led strip + * @length: all the num of leds on the led strip + * @led_num: the specified led that you want to set + * @brightness: the led brightness data + */ +int sunxi_set_led_brightness(unsigned int length, unsigned int led_num, unsigned int brightness) { u32 reg_val; int i, ret; @@ -747,12 +767,13 @@ int sunxi_set_led_brightness(int led_num, unsigned int brightness) return -1; } - if (led_num > led->config.led_count) { + if (length > led->config.led_count || len_num > length) { led_err("has not the %d led\n", led_num); return -1; } - led->config.length = led_num; + led->config.length = length; + /* set the specified led brightness, others set default brightness: 0x0*/ led->config.data[led_num-1] = brightness; for (i = 0; i < led_num; i++)
-
回复: D1s ledc驱动代码bug,DMA模式无法使用
@leomini5 我这边没有D1s的板卡,在T113上测试通过,测试1024颗灯,这个可能是RV才有的bug?
-
回复: D1s ledc驱动代码bug,DMA模式无法使用
之前在其他帖发过DMA模式的patch,这里同步下
lichee/linux-5.4/drivers/leds/leds-sunxi.c
// 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(¤t_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");
lichee/linux-5.4/drivers/leds/leds-sunxi.h
/* * Copyright (C) 2018 Allwinner Technology Limited. All rights reserved. * Albert Yu <yuxyun@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. * */ #ifndef __LINUX_LEDS_SUNXI_H #define __LINUX_LEDS_SUNXI_H #include <linux/device.h> #include <linux/list.h> #include <linux/mutex.h> #include <linux/rwsem.h> #include <linux/spinlock.h> #include <linux/timer.h> #include <linux/workqueue.h> #define HEXADECIMAL (0x10) #define REG_INTERVAL (0x04) #define REG_CL (0x0c) #define RESULT_COMPLETE 1 #define RESULT_ERR 2 #define SUNXI_LEDC_REG_BASE_ADDR 0x06700000 #define SUNXI_MAX_LED_COUNT 1024 #define SUNXI_DEFAULT_LED_COUNT 8 #define SUNXI_RESET_TIME_MIN_NS 84 #define SUNXI_RESET_TIME_MAX_NS 327000 #define SUNXI_T1H_MIN_NS 84 #define SUNXI_T1H_MAX_NS 2560 #define SUNXI_T1L_MIN_NS 84 #define SUNXI_T1L_MAX_NS 1280 #define SUNXI_T0H_MIN_NS 84 #define SUNXI_T0H_MAX_NS 1280 #define SUNXI_T0L_MIN_NS 84 #define SUNXI_T0L_MAX_NS 2560 #define SUNXI_WAIT_TIME0_MIN_NS 84 #define SUNXI_WAIT_TIME0_MAX_NS 10000 #define SUNXI_WAIT_TIME1_MIN_NS 84 #define SUNXI_WAIT_TIME1_MAX_NS 85000000000 #define SUNXI_WAIT_DATA_TIME_MIN_NS 84 #define SUNXI_WAIT_DATA_TIME_MAX_NS_IC 655000 #define SUNXI_WAIT_DATA_TIME_MAX_NS_FPGA 20000000 #define SUNXI_LEDC_FIFO_DEPTH 32 /* 32 * 4 bytes */ #define SUNXI_LEDC_FIFO_TRIG_LEVEL 15 #if defined(CONFIG_FPGA_V4_PLATFORM) || defined(CONFIG_FPGA_V7_PLATFORM) #define SUNXI_FPGA_LEDC #endif enum sunxi_ledc_output_mode_val { SUNXI_OUTPUT_GRB = 0 << 6, SUNXI_OUTPUT_GBR = 1 << 6, SUNXI_OUTPUT_RGB = 2 << 6, SUNXI_OUTPUT_RBG = 3 << 6, SUNXI_OUTPUT_BGR = 4 << 6, SUNXI_OUTPUT_BRG = 5 << 6 }; struct sunxi_ledc_output_mode { char *str; enum sunxi_ledc_output_mode_val val; }; enum sunxi_ledc_trans_mode_val { LEDC_TRANS_CPU_MODE, LEDC_TRANS_DMA_MODE }; enum sunxi_ledc_reg { LEDC_CTRL_REG_OFFSET = 0x00, LED_T01_TIMING_CTRL_REG_OFFSET = 0x04, LEDC_DATA_FINISH_CNT_REG_OFFSET = 0x08, LED_RESET_TIMING_CTRL_REG_OFFSET = 0x0c, LEDC_WAIT_TIME0_CTRL_REG = 0x10, LEDC_DATA_REG_OFFSET = 0x14, LEDC_DMA_CTRL_REG = 0x18, LEDC_INT_CTRL_REG_OFFSET = 0x1c, LEDC_INT_STS_REG_OFFSET = 0x20, LEDC_WAIT_TIME1_CTRL_REG = 0x28, LEDC_VER_NUM_REG = 0x2c, LEDC_FIFO_DATA = 0x30, LEDC_TOTAL_REG_SIZE = LEDC_FIFO_DATA + SUNXI_LEDC_FIFO_DEPTH }; enum sunxi_ledc_irq_ctrl_reg { LEDC_TRANS_FINISH_INT_EN = (1 << 0), LEDC_FIFO_CPUREQ_INT_EN = (1 << 1), LEDC_WAITDATA_TIMEOUT_INT_EN = (1 << 3), LEDC_FIFO_OVERFLOW_INT_EN = (1 << 4), LEDC_GLOBAL_INT_EN = (1 << 5), }; enum sunxi_ledc_irq_status_reg { LEDC_TRANS_FINISH_INT = (1 << 0), LEDC_FIFO_CPUREQ_INT = (1 << 1), LEDC_WAITDATA_TIMEOUT_INT = (1 << 3), LEDC_FIFO_OVERFLOW_INT = (1 << 4), LEDC_FIFO_FULL = (1 << 16), LEDC_FIFO_EMPTY = (1 << 17), }; enum sunxi_led_type { LED_TYPE_R, LED_TYPE_G, LED_TYPE_B }; struct sunxi_led_info { enum sunxi_led_type type; struct led_classdev cdev; }; struct sunxi_led_classdev_group { u32 led_num; struct sunxi_led_info r; struct sunxi_led_info g; struct sunxi_led_info b; }; static u32 sunxi_led_regs_offset[] = { LEDC_CTRL_REG_OFFSET, LED_RESET_TIMING_CTRL_REG_OFFSET, LED_T01_TIMING_CTRL_REG_OFFSET, LEDC_WAIT_TIME0_CTRL_REG, LEDC_WAIT_TIME1_CTRL_REG, LEDC_INT_CTRL_REG_OFFSET, #ifndef SUNXI_FPGA_LEDC LEDC_DATA_FINISH_CNT_REG_OFFSET, #endif }; struct sunxi_led { u32 reset_ns; u32 t1h_ns; u32 t1l_ns; u32 t0h_ns; u32 t0l_ns; u32 wait_time0_ns; unsigned long long wait_time1_ns; u32 wait_data_time_ns; u32 irqnum; u32 led_count; u32 *data; u32 length; u8 result; spinlock_t lock; struct device *dev; dma_addr_t src_dma; struct dma_chan *dma_chan; wait_queue_head_t wait; struct timespec64 start_time; struct clk *clk_ledc; struct clk *clk_cpuapb; struct pinctrl *pctrl; void __iomem *iomem_reg_base; struct resource *res; struct sunxi_ledc_output_mode output_mode; struct sunxi_led_classdev_group *pcdev_group; struct dentry *debugfs_dir; char regulator_id[16]; struct regulator *regulator; struct reset_control *reset; u32 regs_backup[ARRAY_SIZE(sunxi_led_regs_offset)]; }; enum { DEBUG_INIT = 1U << 0, DEBUG_SUSPEND = 1U << 1, DEBUG_INFO = 1U << 2, DEBUG_INFO1 = 1U << 3, DEBUG_INFO2 = 1U << 4, }; #endif /* __LINUX_LEDS_SUNXI_H */
kernel/linux-5.4/arch/riscv/boot/dts/sunxi/sun20iw1p1.dtsi
ledc: ledc@2008000 { #address-cells = <1>; #size-cells = <0>; compatible = "allwinner,sunxi-leds"; reg = <0x0 0x02008000 0x0 0x400>; interrupts-extended = <&plic0 36 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "ledcirq"; clocks = <&ccu CLK_LEDC>, <&ccu CLK_BUS_LEDC>; clock-names = "clk_ledc", "clk_cpuapb"; dmas = <&dma 42>, <&dma 42>; dma-names = "rx", "tx"; resets = <&ccu RST_BUS_LEDC>; reset-names = "ledc_reset"; status = "disable"; };
-
回复: R128-S3不支持NAND FLASH吗?还有SPI0端口不能指定到PA24-P29吗
@chen0505 PA引导是BROM不支持,BROM是固化在芯片里的,如果需要修改需要改版芯片
Note Description D/S Datasheet Support but no sample test S/T Support and sample test √ Support and mass produce X Not support (Blank) Can support but not support now Part Number Capacity JEDEC ID PACKAGE R128 Support Status MT29F2G01ABAGDSF-AAT(NW794) 256M 0x2C, 0x24 SOP-16 D/S MT29F1G01ABAFDSF-AAT(NW808) 128M 0x2C, 0x14 SOP-16 D/S MT29F2G01ABAGDWB 256M 0x2C,0x24 SOP-16 D/S W25N01GVZEIG 128M 0xEF 0xAA 0x21 D/S W25N02KVZEIR 256M 0xEF 0xAA 0x22 MX35LF2GE4AB 256M 0xC2 0x22 16-SOP MX35LF1GE4AB 128M 0xC2 0x12 8-WSON √ MX35LF2GE4AD 256M 0xC2 0x26 0x03 8-WSON D/S MX35LF1G24AD 128M 0xC2 0x14 MX35LF4GE4AD 512M GD5F1GQ4UBYIGR 128M 0xC8 0xD1 8-pad 8X6 WSON D/S GD5F2GQ4UB9IGR 256M 0xC8 0xD2 8-pad 8X6 WSON D/S GD5F1GQ4UCYIG 128M 0xC8 0xB1 0x48 WSON8(8x6mm) D/S GD5F1GQ5UEYIG 128M 0xC8 0x51 D/S GD5F2GQ5UEYIGR 256M 0xC8 0x52 GD5F4GQ6UEYIG 512M 0xC8 0x55 F50L1G41LB(2M) -> F50L1G41LB-104YG2M F50L1G41LB-104YG2ME 128M 0xC8 0x01 0x7F 0x7F 0x7F 8-WSON D/S F50L2G41XA 256M 0x2C, 0x24 DS35Q1GA-1B 128M 0xE5 0x71 8-WSON D/S DS35Q2GA-IB 256M 0xE5 0x72 DS35Q2GBXXX 256M 0xE5 0xf2 DS35Q4GMXXX 512M 0xE5 0xf4 DS35X1GBXXX 1G 0xE5 0xF1 8-WSON TC58CVG2S0H 512M 0x98 0xCD TC58CVG0S3HRAIG 128M 0x98 0xC2 8-WSON D/S FS35ND01G-S1F1QWFI 128M 0xCD 0xB1 WSON8(8x6mm) D/S FS35ND01G-S1Y2 128M 0xCD 0xEA WSON8 F35SQA001G 128M 0xCD 0x71 WSON8 √ F35SQA002G 256M 0xCD 0x72 EM73C044VCD-H 128M 0xD5 0x1C 8-WSON EM73E044SNA 128M 0xD5 0x03 8-WSON ZD35Q1GA-IBR 128M 0xba 0x71 8-WSON D/S PN26G01AWSIUG 128M 0xa1, 0xe1 WSON8(8x6mm) XT26G01A 128M 0x0b,0xe1 D/S XT26G02A 256M 0x0b,0xe2 XT26G04A 512M 0x0b,0xe3 WSON8(8x6mm) XT26G01CWSIG 128M 0x0b,0x11 D/S XT26G02CWSIG 256M 0x0b,0x12 XT26G04CWSIG 512M 0x0b,0x13 XT26G02ELGIGA 256M 0x2c, 0x24 FM25S01 128M 0xa1,0xa1 WSON8(8x6mm) FM25S01A 128M 0xa1,0xe4 FM25S02A 256M 0xa1,0xe5 SCN00SA3W1AI8A 128M 0xC8 0x21 8-WSON S35ML01G3 128M 0x01 0x15 S35ML02G300WH100 256M 0x01 0x25 S35ML04G3 512M 0x01 0x35 HYF1GQ4UDACAE 128M 0xC9 0x21 -
回复: R128-S3不支持NAND FLASH吗?还有SPI0端口不能指定到PA24-P29吗
支持NAND的,下图的5个模块分别是NOR和NAND,
启动使用的SPI是在PB组,需要挂在PB上才能启动,并且需要专门配置的SDK,可以在SDK中看到有NAND的选项
附上两种存储介质的启动流程:
NOR:
NAND:
同时也支持 eMMC、SD-NAND启动
-
回复: V853 SDK:Linux内核中的MIPI DSI
从 log中可以看到,
[ 0.293211] disp 0, clk: pll(426000000),clk(426000000),dclk(71000000) dsi_rate(71000000) [ 0.293211] clk real:pll(420000000),clk(420000000),dclk(105000000) dsi_rate(150000000)
内核引脚正确初始化并执行送图,Uboot运行而Kernel不执行函数是因为Kernel驱动当接收到Uboot传入的显示屏信息后不会重新初始化屏幕,这样可以保证整个开机logo显示流畅。
这里log看到的驱动是ICN6202 TO LVDS,这是一颗转换MIPI DSI 转 LVDS的芯片,其MIPI初始化数据与普通 MIPI 屏幕不同,请检查下是否使用了正确的初始化。
MIPI 与 RGB 不同,MIPI需要配置屏幕的参数,需要针对屏幕编写驱动
-
回复: MQ-Quad H616 主线内核编译调试记录(u-boot、kernel、buildroot)
@king-zhao aw859a 的 WIFI 驱动可以在 OrangePi 官方仓库里找到
-
回复: 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
-
回复: SyterKit 启动 T527 失败
修改设备树,增加memory和chosen
/* * Allwinner Technology CO., Ltd. */ /dts-v1/; #include "sun55iw3p1.dtsi" /{ board = "T527", "T527-LM4B"; compatible = "allwinner,t527", "arm,sun55iw3p1"; chosen { bootargs = "earlycon=uart8250,mmio32,0x02500000 clk_ignore_unused initcall_debug=0 console=ttyAS0,115200 loglevel=8 init=/init cma=64M"; }; memory@40000000 { device_type = "memory"; reg = <0x00000000 0x40000000 0x00000000 0x20000000>; }; aliases { pmu0 = &pmu0; serial0 = &uart0; hdmi = &hdmi; reg-axp1530 = ®_ext_axp1530_dcdc1; axp1530 = &axp1530; cpu-ext = &cpu4; standby-param = &standby_param; arisc-config = &arisc_config; cir_param = &cir_param; }; reg_usb0_vbus: usb0-vbus { compatible = "regulator-fixed"; regulator-name = "usb0-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; regulator-enable-ramp-delay = <1000>; gpio = <&pio PB 12 GPIO_ACTIVE_HIGH>; enable-active-high; }; reg_usb1_vbus: usb1-vbus { compatible = "regulator-fixed"; regulator-name = "usb1-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; regulator-enable-ramp-delay = <1000>; gpio = <&pio PB 3 GPIO_ACTIVE_HIGH>; enable-active-high; }; standby_param: standby_param { vdd-cpu = <0x00000001>; vdd-cpub = <0x00000001>; vdd-sys = <0x00000002>; vcc-pll = <0x00000080>; vcc-io = <0x00004000>; osc24m-on = <0x0>; }; cir_param: cir_param { gpio_group = <1>; /* 0:PL 1:PM */ gpio_pin = <11>; gpio_function = <2>; count = <15>; ir_power_key_code0 = <0x40>; ir_addr_code0 = <0xfe01>; ir_power_key_code1 = <0x1a>; ir_addr_code1 = <0xfb04>; ir_power_key_code2 = <0xf2>; ir_addr_code2 = <0x2992>; ir_power_key_code3 = <0x57>; ir_addr_code3 = <0x9f00>; ir_power_key_code4 = <0xdc>; ir_addr_code4 = <0x4cb3>; ir_power_key_code5 = <0x18>; ir_addr_code5 = <0xff00>; ir_power_key_code6 = <0xdc>; ir_addr_code6 = <0xdd22>; ir_power_key_code7 = <0x0d>; ir_addr_code7 = <0xbc00>; ir_power_key_code8 = <0x4d>; ir_addr_code8 = <0x4040>; ir_power_key_code9 = <0x08>; ir_addr_code9 = <0xfb04>; ir_power_key_code10 = <0x00>; ir_addr_code10 = <0xfc03>; ir_power_key_code11 = <0x00>; ir_addr_code11 = <0xbf00>; ir_power_key_code12 = <0xea>; ir_addr_code12 = <0xfb04>; ir_power_key_code13 = <0x42>; ir_addr_code13 = <0xbf00>; ir_power_key_code14 = <0x0f>; ir_addr_code14 = <0xff00>; }; arisc_config: arisc_config { s_uart_config { pins = "PL2", "PL3"; function = <2>, <2>; status = "disabled"; }; }; edp_panel_backlight: edp_backlight { compatible = "pwm-backlight"; status = "disabled"; brightness-levels = < 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255>; default-brightness-level = <200>; enable-gpios = <&pio PI 5 GPIO_ACTIVE_HIGH>; /* power-supply = <®_backlight_12v>; */ pwms = <&pwm0 5 5000000 0>; }; edp_panel: edp_panel { compatible = "edp-general-panel"; status = "okay"; power0-supply = <®_dcdc4>; backlight = <&edp_panel_backlight>; panel-timing { clock-frequency = <348577920>; /* pixel clock */ hactive = <2560>; hback-porch = <120>; hfront-porch = <88>; hsync-len = <32>; vactive = <1600>; vback-porch = <71>; vfront-porch = <28>; vsync-len = <5>; /* hor_sync_polarity */ hsync-active = <1>; /* ver_sync_polarity */ vsync-active = <1>; // unused now /* de-active = <1>; pixelclk-active = <1>; syncclk-active = <0>; interlaced; doublescan; doubleclk; */ }; ports { #address-cells = <1>; #size-cells = <0>; panel_in: port@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; edp_panel_in: endpoint@0 { reg = <0>; remote-endpoint = <&edp_panel_out>; }; }; }; }; lvds_panel0_backlight: backlight0 { compatible = "pwm-backlight"; status = "okay"; brightness-levels = < 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255>; default-brightness-level = <200>; enable-gpios = <&pio PI 2 GPIO_ACTIVE_HIGH>; pwms = <&pwm0 4 50000 0>; }; lvds_panel0: panel@0 { compatible = "BP101WX1"; status = "okay"; reg = <0>; power0-supply = <®_cldo3>; power1-supply = <®_dcdc4>; power2-supply = <®_cldo1>; backlight = <&lvds_panel0_backlight>; lcd_if = <3>; lcd_width = <150>; lcd_height = <94>; pinctrl-0 = <&lvds0_pins_a>; pinctrl-1 = <&lvds0_pins_b>; pinctrl-names = "active","sleep"; panel-timing { clock-frequency = <74871600>; /* pixel clock */ hback-porch = <88>; hactive = <1280>; hfront-porch = <83>; hsync-len = <18>; vback-porch = <23>; vactive = <800>; vfront-porch = <37>; vsync-len = <10>; // unused now /* hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <1>; */ }; ports { #address-cells = <1>; #size-cells = <0>; lvds_panel0_in: port@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; lvds_panel0_in_lcd0: endpoint@0 { reg = <0>; remote-endpoint = <&tcon0_out_panel>; }; }; }; }; lvds_panel1: panel@1 { compatible = "BP101WX1"; status = "disabled"; reg = <1>; power0-supply = <®_cldo3>; power1-supply = <®_dcdc4>; backlight = <&lvds_panel1_backlight>; lcd_if = <3>; lcd_width = <150>; lcd_height = <94>; pinctrl-0 = <&lvds2_pins_a>; pinctrl-1 = <&lvds2_pins_b>; pinctrl-names = "active","sleep"; panel-timing { clock-frequency = <74871600>; /* pixel clock */ hback-porch = <88>; hactive = <1280>; hfront-porch = <83>; hsync-len = <18>; vback-porch = <23>; vactive = <800>; vfront-porch = <37>; vsync-len = <10>; // unused now /* hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <1>; */ }; ports { #address-cells = <1>; #size-cells = <0>; lvds_panel1_in: port@0 { #address-cells = <1>; #size-cells = <0>; reg = <0>; lvds_panel1_in_lcd2: endpoint@0 { reg = <0>; remote-endpoint = <&tcon4_out_panel>; }; }; }; }; lvds_panel1_backlight: backlight1 { compatible = "pwm-backlight"; status = "disabled"; brightness-levels = < 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255>; default-brightness-level = <200>; enable-gpios = <&pio PI 5 GPIO_ACTIVE_HIGH>; pwms = <&pwm0 5 5000000 0>; }; }; &de { chn_cfg_mode = <3>; status = "okay"; }; &vo0 { status = "okay"; }; &vo1 { status = "okay"; }; &tv0 { status = "okay"; }; &dlcd0 { status = "okay"; panel = <&lvds_panel0>; ports { tcon0_out: port@1 { tcon0_out_panel: endpoint@2 { reg = <2>; remote-endpoint = <&lvds_panel0_in_lcd0>; }; }; }; }; &dlcd2 { status = "disabled"; panel = <&lvds_panel1>; ports { tcon4_out: port@1 { tcon4_out_panel: endpoint@0 { reg = <0>; remote-endpoint = <&lvds_panel1_in_lcd2>; }; }; }; }; &dsi0combophy { status = "okay"; }; &dsi1combophy { status = "okay"; }; &drm_edp { status = "disabled"; edp_ssc_en = <0>; edp_ssc_mode = <0>; edp_psr_support = <0>; edp_colordepth = <8>; /* 6/8/10/12/16 */ edp_color_fmt = <0>; /* 0:RGB 1: YUV444 2: YUV422 */ lane1_sw = <0>; lane1_pre = <0>; lane2_sw = <0>; lane2_pre = <0>; lane3_sw = <0>; lane3_pre = <0>; efficient_training = <0>; sink_capacity_prefer = <1>; edid_timings_prefer = <1>; timings_fixed = <1>; vcc-edp-supply = <®_bldo3>; vdd-edp-supply = <®_dcdc2>; panel = <&edp_panel>; ports { edp_out: port@1 { edp_panel_out: endpoint@0 { reg = <0>; remote-endpoint = <&edp_panel_in>; }; }; }; }; &r_pio { uart8_pins_a: uart8_pins@0 { pins = "PL2", "PL3"; function = "s_uart0"; }; uart8_pins_b: uart8_pins@1 { pins = "PL2", "PL3"; function = "gpio_in"; }; uart9_pins_a: uart9_pins@0 { pins = "PM0", "PM1"; function = "s_uart1"; }; uart9_pins_b: uart9_pins@1 { pins = "PM0", "PM1"; function = "gpio_in"; }; s_twi0_pins_default: s_twi0@0 { pins = "PL0", "PL1"; function = "s_twi0"; drive-strength = <10>; bias-pull-up; }; s_twi0_pins_sleep: s_twi0@1 { pins = "PL0", "PL1"; function = "gpio_in"; }; s_twi1_pins_default: s_twi1@0 { pins = "PL8", "PL9"; function = "s_twi1"; drive-strength = <10>; bias-pull-up; }; s_twi1_pins_sleep: s_twi1@1 { pins = "PL8", "PL9"; function = "gpio_in"; }; s_twi2_pins_default: s_twi2@0 { pins = "PL12", "PL13"; function = "s_twi2"; drive-strength = <10>; bias-pull-up; }; s_twi2_pins_sleep: s_twi2@1 { pins = "PL12", "PL13"; function = "gpio_in"; }; s_irrx_pins_default: s_irrx@0 { pins = "PL11"; function = "s_cir"; }; s_irrx_pins_sleep: s_irrx@1 { pins = "PL11"; function = "gpio_in"; }; }; &pio { vcc-pg-supply = <®_pio1_8>; vcc-pf-supply = <®_pio1_8>; vcc-pfo-supply = <®_pio3_3>; vcc-pd-supply = <®_dcdc4>; vcc-pe-supply = <®_pio1_8>; vcc-pi-supply = <®_dcdc4>; vcc-pj-supply = <®_dcdc4>; vcc-pk-supply = <®_dcdc4>; uart0_pins_a: uart0_pins@0 { pins = "", ""; function = "uart0"; }; uart0_pins_b: uart0_pins@1 { pins = "", ""; function = "gpio_in"; }; uart2_pins_a: uart2_pins@0 { pins = "PB0", "PB1"; function = "uart2"; }; uart2_pins_b: uart2_pins@1 { pins = "PB0", "PB1"; function = "gpio_in"; }; uart3_pins_a: uart3_pins@0 { pins = "PD14", "PD15"; function = "uart3"; }; uart3_pins_b: uart3_pins@1 { pins = "PD14", "PD15"; function = "gpio_in"; }; uart4_pins_a: uart4_pins@0 { pins = "PD18", "PD19"; function = "uart4"; }; uart4_pins_b: uart4_pins@1 { pins = "PD18", "PD19"; function = "gpio_in"; }; uart5_pins_a: uart5_pins@0 { pins = "PE11", "PE12"; function = "uart5"; }; uart5_pins_b: uart5_pins@1 { pins = "PE11", "PE12"; function = "gpio_in"; }; uart6_pins_a: uart6_pins@0 { pins = "PI6", "PI7"; function = "uart6"; }; uart6_pins_b: uart6_pins@1 { pins = "PI6", "PI7"; function = "gpio_in"; }; uart7_pins_a: uart7_pins@0 { pins = "PB11", "PB12"; function = "uart7"; }; uart7_pins_b: uart7_pins@1 { pins = "PB11", "PB12"; function = "gpio_in"; }; pwm0_0_pin_active: pwm0_0@0 { pins = "PD23"; function = "pwm0_0"; }; pwm0_0_pin_sleep: pwm0_0@1 { pins = "PD23"; function = "gpio_in"; bias-pull-down; }; pwm0_1_pin_active: pwm0_1@0 { pins = "PD22"; function = "pwm0_1"; }; pwm0_1_pin_sleep: pwm0_1@1 { pins = "PD22"; function = "gpio_in"; bias-pull-down; }; pwm0_2_pin_active: pwm0_2@0 { pins = "PB11"; function = "pwm0_2"; }; pwm0_2_pin_sleep: pwm0_2@1 { pins = "PB11"; function = "gpio_in"; bias-pull-down; }; pwm0_3_pin_active: pwm0_3@0 { pins = "PB12"; function = "pwm0_3"; }; pwm0_3_pin_sleep: pwm0_3@1 { pins = "PB12"; function = "gpio_in"; bias-pull-down; }; pwm0_4_pin_active: pwm0_4@0 { pins = "PI3"; function = "pwm0_4"; }; pwm0_4_pin_sleep: pwm0_4@1 { pins = "PI3"; function = "gpio_in"; bias-pull-down; }; pwm0_5_pin_active: pwm0_5@0 { pins = "PI4"; function = "pwm0_5"; }; pwm0_5_pin_sleep: pwm0_5@1 { pins = "PI4"; function = "gpio_in"; bias-pull-down; }; ledc_pins_a: ledc@0 { pins = "PG0"; function = "ledc"; drive-strength = <10>; }; ledc_pins_b: ledc@1 { pins = "PG0"; function = "gpio_in"; }; irrx_pins_default: irrx@0 { pins = "PI8"; function = "cir"; }; irrx_pins_sleep: irrx@1 { pins = "PI8"; function = "gpio_in"; }; irtx_pins_default: irtx@0 { pins = "PH18"; function = "cir"; }; irtx_pins_sleep: irtx@1 { pins = "PH18"; function = "gpio_in"; }; twi0_pins_default: twi0@0 { pins = "PD22", "PD23"; function = "twi0"; drive-strength = <10>; bias-pull-up; }; twi0_pins_sleep: twi0@1 { pins = "PD22", "PD23"; function = "gpio_in"; }; twi1_pins_default: twi1@0 { pins = "PH2", "PH3"; function = "twi1"; drive-strength = <10>; bias-pull-up; }; twi1_pins_sleep: twi1@1 { pins = "PH2", "PH3"; function = "gpio_in"; }; twi2_pins_default: twi2@0 { pins = "PE1", "PE2"; function = "twi2"; drive-strength = <20>; bias-pull-up; }; twi2_pins_sleep: twi2@1 { pins = "PE1", "PE2"; function = "gpio_in"; }; twi3_pins_default: twi3@0 { pins = "PE3", "PE4"; function = "twi3"; drive-strength = <20>; bias-pull-up; }; twi3_pins_sleep: twi3@1 { pins = "PE3", "PE4"; function = "gpio_in"; }; twi4_pins_default: twi4@0 { pins = "PE13", "PE14"; function = "twi4"; drive-strength = <10>; bias-pull-up; }; twi4_pins_sleep: twi4@1 { pins = "PE13", "PE14"; function = "gpio_in"; }; twi5_pins_default: twi5@0 { pins = "PI8", "PI9"; function = "twi5"; drive-strength = <10>; bias-pull-up; }; twi5_pins_sleep: twi5@1 { pins = "PI8", "PI9"; function = "gpio_in"; }; owa_pins_a: owa@0 { pins = "PI10"; function = "owa"; drive-strength = <20>; bias-disable; }; owa_pins_b: owa@1 { pins = "PI10"; function = "io_disabled"; drive-strength = <20>; bias-disable; }; i2s0_pins_a: i2s0@0 { pins = "PB4", "PB5", "PB6"; function = "i2s0"; drive-strength = <20>; bias-disable; }; i2s0_pins_b: i2s0@1 { pins = "PB4", "PB5", "PB6", "PB7", "PB8"; function = "io_disabled"; drive-strength = <20>; bias-disable; }; i2s0_pins_c: i2s0@2 { pins = "PB7"; function = "i2s0_dout"; drive-strength = <20>; bias-disable; }; i2s0_pins_d: i2s0@3 { pins = "PB8"; function = "i2s0_din"; drive-strength = <20>; bias-disable; }; i2s1_pins_a: i2s1@0 { pins = "PG10", "PG11", "PG12"; function = "i2s1"; drive-strength = <20>; bias-disable; }; i2s1_pins_b: i2s1@1 { pins = "PG10", "PG11", "PG12", "PG13", "PG14"; function = "io_disabled"; drive-strength = <20>; bias-disable; }; i2s1_pins_c: i2s1@2 { pins = "PG13"; function = "i2s1_dout"; drive-strength = <20>; bias-disable; }; i2s1_pins_d: i2s1@3 { pins = "PG14"; function = "i2s1_din"; drive-strength = <20>; bias-disable; }; i2s2_pins_a: i2s2@0 { pins = "PH9", "PH10"; function = "i2s2"; drive-strength = <20>; bias-disable; }; i2s2_pins_b: i2s2@1 { pins = "PH2", "PH3", "PH8", "PH9", "PH10", "PH11", "PH12"; function = "io_disabled"; drive-strength = <20>; bias-disable; }; i2s2_pins_c: i2s2@2 { pins = "PH2", "PH3", "PH12"; function = "i2s2_din"; drive-strength = <20>; bias-disable; }; i2s2_pins_d: i2s2@3 { pins = "PH11"; function = "i2s2_dout"; drive-strength = <20>; bias-disable; }; i2s2_pins_e: i2s2@4 { pins = "PH8"; function = "i2s2_mclk"; drive-strength = <20>; bias-disable; }; i2s3_pins_a: i2s3@0 { pins = "PF3", "PF5", "PF6"; function = "i2s3"; drive-strength = <20>; bias-disable; }; i2s3_pins_b: i2s3@1 { pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5", "PF6"; function = "io_disabled"; drive-strength = <20>; bias-disable; }; i2s3_pins_c: i2s3@2 { pins = "PF0", "PF2", "PF4"; function = "i2s3_din"; drive-strength = <20>; bias-disable; }; i2s3_pins_d: i2s3@3 { pins = "PF1"; function = "i2s3_dout"; drive-strength = <20>; bias-disable; }; rgb24_pins_a: rgb24@0 { pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", \ "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PD16", "PD17", "PD18", "PD19", \ "PD20", "PD21", "PD22","PD23","PD24","PD25","PD26","PD27"; function = "dpss"; drive-strength = <30>; }; rgb24_pins_b: rgb24@1 { pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9", \ "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", "PD16", "PD17", "PD18", "PD19", \ "PD20", "PD21", "PD22", "PD23","PD24","PD25","PD26","PD27"; function = "gpio_in"; }; lvds0_pins_a: lvds0@0 { pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9"; function = "lvds0"; drive-strength = <30>; }; lvds0_pins_b: lvds0@1 { pins = "PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9"; function = "gpio_in"; }; nand0_pins_default: nand0@0 { pins = "PC0", "PC1", "PC2", "PC5", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PC16"; function = "nand0"; drive-strength = <30>; }; nand0_pins_rb: nand0@1 { pins = "PC4", "PC6", "PC3", "PC7"; function = "nand0"; drive-strength = <30>; bias-pull-up; /* only RB&CE should be pulled up */ }; nand0_pins_sleep: nand0@2 { pins = "PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", "PC15", "PC16"; function = "io_disabled"; drive-strength = <10>; }; gmac0_pins_default: gmac0@0 { pins = "PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH9", "PH10","PH13","PH14", "PH15","PH16","PH17","PH18"; drive-strength = <40>; function = "gmac0"; bias-pull-up; }; gmac0_pins_sleep: gmac0@1 { pins = "PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH9", "PH10","PH13","PH14", "PH15","PH16","PH17","PH18"; function = "gpio_in"; }; gmac1_pins_default: gmac1@0 { pins = "PJ0", "PJ1", "PJ2", "PJ3", "PJ4", "PJ5", "PJ6", "PJ7", "PJ8", "PJ9", "PJ10", "PJ11", "PJ12","PJ13", "PJ14", "PJ15"; drive-strength = <40>; function = "gmac1"; bias-pull-up; }; gmac1_pins_sleep: gmac1@1 { pins = "PJ0", "PJ1", "PJ2", "PJ3", "PJ4", "PJ5", "PJ6", "PJ7", "PJ8", "PJ9", "PJ10", "PJ11", "PJ12","PJ13", "PJ14", "PJ15"; function = "gpio_in"; }; }; &soc { auto_print@54321 { reg = <0x0 0x54321 0x0 0x0>; device_type = "auto_print"; status = "okay"; }; gpio_leds { compatible = "allwinner,sunxi-gpio-leds"; supply-num = <1>; gpio1-supply = <®_bldo1>; gpio-pins = <&pio PG 10 GPIO_ACTIVE_LOW>, <&pio PC 7 GPIO_ACTIVE_LOW>; pin-names = "normal_led", "standby_led"; init-status = <GPIO_ACTIVE_HIGH>, <GPIO_ACTIVE_LOW>; status = "okay"; }; }; &uart0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pins_a>; pinctrl-1 = <&uart0_pins_b>; uart-supply = <®_cldo3>; status = "okay"; }; &uart1 { status = "okay"; }; &uart2 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart2_pins_a>; pinctrl-1 = <&uart2_pins_b>; status = "disabled"; }; &uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_a>; pinctrl-1 = <&uart3_pins_b>; status = "disabled"; }; &uart4 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart4_pins_a>; pinctrl-1 = <&uart4_pins_b>; status = "disabled"; }; &uart5 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart5_pins_a>; pinctrl-1 = <&uart5_pins_b>; status = "disabled"; }; &uart6 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart6_pins_a>; pinctrl-1 = <&uart6_pins_b>; status = "okay"; }; &uart7 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart7_pins_a>; pinctrl-1 = <&uart7_pins_b>; status = "disabled"; }; &uart8 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart8_pins_a>; pinctrl-1 = <&uart8_pins_b>; status = "disabled"; }; &uart9 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart9_pins_a>; pinctrl-1 = <&uart9_pins_b>; status = "disabled"; }; &lradc { key_cnt = <5>; key0 = <210 0x73>; key1 = <410 0x72>; key2 = <590 0x8B>; key3 = <750 0x1c>; key4 = <880 0x66>; key_debounce; debounce_value = <50>; status = "disabled"; }; &irrx { pinctrl-names = "default", "sleep"; pinctrl-0 = <&irrx_pins_default>; pinctrl-1 = <&irrx_pins_sleep>; status = "disabled"; }; &s_irrx { pinctrl-names = "default", "sleep"; pinctrl-0 = <&s_irrx_pins_default>; pinctrl-1 = <&s_irrx_pins_sleep>; status = "okay"; }; &irtx { pinctrl-names = "default", "sleep"; pinctrl-0 = <&irtx_pins_default>; pinctrl-1 = <&irtx_pins_sleep>; status = "disabled"; }; &gpadc0 { channel_num = <2>; channel_select = <3>; channel_data_select = <3>; channel_compare_select = <3>; channel_cld_select = <3>; channel_chd_select = <3>; channel0_compare_lowdata = <1700000>; channel0_compare_higdata = <1200000>; channel1_compare_lowdata = <460000>; channel1_compare_higdata = <1200000>; status = "disabled"; }; &gpadc1 { channel_num = <2>; channel_select = <3>; channel_data_select = <3>; channel_compare_select = <3>; channel_cld_select = <3>; channel_chd_select = <3>; channel0_compare_lowdata = <1700000>; channel0_compare_higdata = <1200000>; channel1_compare_lowdata = <460000>; channel1_compare_higdata = <1200000>; status = "disabled"; }; &pwm0_0 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_0_pin_active>; pinctrl-1 = <&pwm0_0_pin_sleep>; status = "okay"; }; &pwm0_1 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_1_pin_active>; pinctrl-1 = <&pwm0_1_pin_sleep>; status = "disabled"; }; &pwm0_2 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_2_pin_active>; pinctrl-1 = <&pwm0_2_pin_sleep>; status = "disabled"; }; &pwm0_3 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_3_pin_active>; pinctrl-1 = <&pwm0_3_pin_sleep>; status = "disabled"; }; &pwm0_4 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_4_pin_active>; pinctrl-1 = <&pwm0_4_pin_sleep>; status = "okay"; }; &pwm0_5 { pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_5_pin_active>; pinctrl-1 = <&pwm0_5_pin_sleep>; status = "okay"; }; &ledc { pinctrl-names = "default", "sleep"; pinctrl-0 = <&ledc_pins_a>; pinctrl-1 = <&ledc_pins_b>; led_count = <34>; output_mode = "GRB"; reset_ns = <84>; t1h_ns = <800>; t1l_ns = <320>; t0h_ns = <300>; t0l_ns = <800>; wait_time0_ns = <84>; wait_time1_ns = <84>; wait_data_time_ns = <600000>; status = "disabled"; }; &twi0 { clock-frequency = <400000>; pinctrl-0 = <&twi0_pins_default>; pinctrl-1 = <&twi0_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_dcdc4>; status = "disabled"; eeprom@50 { compatible = "atmel,24c16"; reg = <0x50>; status = "okay"; }; pcie_usb_phy@74 { compatible = "combphy,phy74"; reg = <0x74>; status = "disabled"; }; pcie_usb_phy@75 { compatible = "combphy,phy75"; reg = <0x75>; status = "disabled"; }; ctp { compatible = "allwinner,goodix"; reg = <0x5d>; device_type = "ctp"; status = "disabled"; ctp_name = "gt9xxnew_ts"; ctp_twi_id = <0x0>; ctp_twi_addr = <0x5d>; ctp_screen_max_x = <0x320>; ctp_screen_max_y = <0x500>; ctp_revert_x_flag = <0x1>; ctp_revert_y_flag = <0x1>; ctp_exchange_x_y_flag = <0x0>; ctp_int_port = <&pio PH 9 GPIO_ACTIVE_LOW>; ctp_wakeup = <&pio PH 10 GPIO_ACTIVE_LOW>; ctp-supply = <®_cldo2>; ctp_power_ldo_vol = <3300>; }; gt9xx { compatible = "goodix,gt9xx"; reg = <0x5d>; status = "okay"; irq-gpios = <&pio PD 20 GPIO_ACTIVE_LOW>; irq-flags = <2>; reset-gpios = <&pio PD 21 GPIO_ACTIVE_LOW>; vdd_ana-supply = <®_dcdc4>; touchscreen-max-id = <11>; touchscreen-size-x = <1280>; touchscreen-size-y = <800>; touchscreen-max-w = <512>; touchscreen-max-p = <512>; //touchscreen-key-map = <172>, <158>; /*KEY_HOMEPAGE=172, KEY_BACK=158,KEY_MENU=139*/ goodix,slide-wakeup = <0>; goodix,type-a-report = <1>; goodix,driver-send-cfg = <0>; goodix,send-cfg-id = <0>; goodix,resume-in-workqueue = <0>; goodix,int-sync = <1>; goodix,revert_x = <0>; goodix,revert_y = <0>; goodix,swap-x2y = <0>; goodix,tp_idle_support = <1>; goodix,esd-protect = <1>; goodix,auto-update-cfg = <0>; goodix,power-off-sleep = <1>; goodix,pen-suppress-finger = <0>; /* GT9271_Config_20221222_v67.cfg*/ goodix,cfg-group0 = [ B4 00 05 20 03 0A 3D 00 01 0A 28 0F 50 32 03 05 00 00 00 00 00 00 06 17 19 1F 14 8E 2E 99 2D 2F 35 11 00 00 00 1A 03 10 00 00 00 00 00 00 00 00 00 00 00 32 50 94 D5 02 07 00 00 04 8E 48 00 8A 4D 00 86 53 00 83 59 00 80 60 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 04 05 06 07 08 09 0C 0D 0E 0F 10 11 14 15 16 17 FF FF FF FF FF FF FF FF FF FF FF FF 28 27 26 25 24 23 22 21 20 1F 1E 1C 1B 19 13 12 11 10 0F 0D 0C 0A 08 07 06 04 02 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF AB 01 ]; }; }; &twi1 { clock-frequency = <400000>; pinctrl-0 = <&twi1_pins_default>; pinctrl-1 = <&twi1_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; status = "disabled"; mir3da { compatible = "allwinner,mir3da"; reg = <0x26>; device_type = "gsensor"; status = "disabled"; gsensor_twi_id = <0x1>; gsensor_twi_addr = <0x26>; gsensor_int1 = <&pio PH 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; gsensor-supply = <®_cldo3>; gsensor_vcc_io_val = <3300>; }; }; &twi2 { clock-frequency = <400000>; pinctrl-0 = <&twi2_pins_default>; pinctrl-1 = <&twi2_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_dcdc4>; status = "okay"; }; &twi3 { clock-frequency = <400000>; pinctrl-0 = <&twi3_pins_default>; pinctrl-1 = <&twi3_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_dcdc4>; status = "okay"; }; &twi4 { clock-frequency = <400000>; pinctrl-0 = <&twi4_pins_default>; pinctrl-1 = <&twi4_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_dcdc4>; status = "okay"; }; &twi5 { clock-frequency = <400000>; pinctrl-0 = <&twi5_pins_default>; pinctrl-1 = <&twi5_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_dcdc4>; status = "disabled"; gt9xx_secondary { compatible = "goodix,gt9xx_secondary"; reg = <0x5d>; status = "okay"; irq-gpios = <&pio PI 13 GPIO_ACTIVE_LOW>; irq-flags = <2>; reset-gpios = <&pio PI 14 GPIO_ACTIVE_LOW>; vdd_ana-supply = <®_dcdc4>; touchscreen-max-id = <11>; touchscreen-size-x = <1280>; touchscreen-size-y = <800>; touchscreen-max-w = <512>; touchscreen-max-p = <512>; //touchscreen-key-map = <172>, <158>; /*KEY_HOMEPAGE=172, KEY_BACK=158,KEY_MENU=139*/ goodix,slide-wakeup = <0>; goodix,type-a-report = <1>; goodix,driver-send-cfg = <0>; goodix,send-cfg-id = <0>; goodix,resume-in-workqueue = <0>; goodix,int-sync = <1>; goodix,revert_x = <0>; goodix,revert_y = <0>; goodix,swap-x2y = <0>; goodix,tp_idle_support = <1>; goodix,esd-protect = <1>; goodix,auto-update-cfg = <0>; goodix,power-off-sleep = <1>; goodix,pen-suppress-finger = <0>; /* GT9271_Config_20221222_v67.cfg*/ goodix,cfg-group0 = [ 43 B0 04 80 07 0A 35 00 01 08 28 0F 50 32 03 05 00 00 00 00 00 00 00 17 19 1B 14 90 2B 99 2F 31 8E 12 00 00 00 DA 03 10 00 00 00 00 00 00 00 00 00 11 00 29 4B 94 C5 02 07 00 00 04 85 2B 00 7D 31 00 77 37 00 72 3E 00 6F 46 00 6F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 00 00 00 00 17 16 15 14 11 10 0F 0E 0D 0C 09 08 07 06 05 04 01 00 FF FF FF FF FF FF 00 00 00 00 00 00 25 24 23 22 21 20 1F 1E 1C 1B 19 14 13 12 11 10 0F 0E 0D 0C 0A 08 07 06 04 02 00 FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 73 01 ]; }; }; &csi_mclk3_pins_a { pins = "PK13"; function = "ncsi"; }; &csi_mclk3_pins_b { pins = "PK13"; }; &mipib_4lane_pins_a { pins = "PK6", "PK7", "PK8", "PK9"; }; &mipib_4lane_pins_b { pins = "PK6", "PK7", "PK8", "PK9"; }; &vind0 { csi_top = <360000000>; csi_isp = <300000000>; vind_mclkpin-supply = <®_bldo3>; /* vcc-pe */ vind_mclkpin_vol = <1800000>; vind_mcsipin-supply = <®_bldo3>; /* vcc-pk */ vind_mcsipin_vol = <1800000>; vind_mipipin-supply = <®_bldo3>; /* vcc-mcsi */ vind_mipipin_vol = <1800000>; status = "okay"; csi3:csi@5823000 { pinctrl-names = "default","sleep"; pinctrl-0 = <&ncsi_bt1120_pins_a>; pinctrl-1 = <&ncsi_bt1120_pins_b>; status = "okay"; }; tdm0:tdm@5908000 { work_mode = <0>; }; isp00:isp@5900000 { work_mode = <0>; }; isp01:isp@58ffffc { status = "disabled"; }; isp02:isp@58ffff8 { status = "disabled"; }; isp03:isp@58ffff4 { status = "disabled"; }; isp10:isp@4 { status = "okay"; }; isp20:isp@5 { status = "okay"; }; scaler00:scaler@5910000 { work_mode = <0>; }; scaler01:scaler@590fffc { status = "disabled"; }; scaler02:scaler@590fff8 { status = "disabled"; }; scaler03:scaler@590fff4 { status = "disabled"; }; scaler10:scaler@5910400 { work_mode = <0>; }; scaler11:scaler@59103fc { status = "disabled"; }; scaler12:scaler@59103f8 { status = "disabled"; }; scaler13:scaler@59103f4 { status = "disabled"; }; scaler20:scaler@5910800 { work_mode = <0>; }; scaler21:scaler@59107fc { status = "disabled"; }; scaler22:scaler@59107f8 { status = "disabled"; }; scaler23:scaler@59107f4 { status = "disabled"; }; scaler30:scaler@5910c00 { work_mode = <0>; }; scaler31:scaler@5910bfc { status = "disabled"; }; scaler32:scaler@5910bf8 { status = "disabled"; }; scaler33:scaler@5910bf4 { status = "disabled"; }; scaler40:scaler@16 { status = "okay"; }; scaler50:scaler@17 { status = "okay"; }; actuator0: actuator@2108180 { device_type = "actuator0"; actuator0_name = "dw9714_act"; actuator0_slave = <0x18>; actuator0_af_pwdn = <>; actuator0_afvdd = "afvcc-csi"; actuator0_afvdd_vol = <2800000>; status = "disabled"; }; flash0: flash@2108190 { device_type = "flash0"; flash0_type = <2>; flash0_en = <&r_pio PL 11 GPIO_ACTIVE_LOW>; flash0_mode = <>; flash0_flvdd = ""; flash0_flvdd_vol = <>; device_id = <0>; status = "disabled"; }; sensor0:sensor@5812000 { device_type = "sensor0"; sensor0_mname = "tp2815_mipi"; sensor0_twi_cci_id = <2>; sensor0_twi_addr = <0x88>; sensor0_mclk_id = <0>; sensor0_pos = "rear"; sensor0_isp_used = <0>; sensor0_fmt = <0>; sensor0_stby_mode = <0>; sensor0_vflip = <0>; sensor0_hflip = <0>; sensor0_cameravdd-supply = <>; sensor0_cameravdd_vol = <>; sensor0_iovdd-supply = <>; sensor0_iovdd_vol = <>; sensor0_avdd-supply = <>; sensor0_avdd_vol = <>; sensor0_dvdd-supply = <>; sensor0_dvdd_vol = <>; sensor0_power_en = <>; sensor0_reset = <&pio PK 11 GPIO_ACTIVE_LOW>; sensor0_pwdn = <>; status = "okay"; }; sensor1:sensor@5812010 { device_type = "sensor1"; sensor1_mname = "nvp6158"; sensor1_twi_cci_id = <3>; sensor1_twi_addr = <0x64>; sensor1_mclk_id = <3>; sensor1_pos = "front"; sensor1_isp_used = <0>; sensor1_fmt = <0>; sensor1_stby_mode = <0>; sensor1_vflip = <0>; sensor1_hflip = <0>; sensor1_iovdd-supply = <>; sensor1_iovdd_vol = <>; sensor1_avdd-supply = <>; sensor1_avdd_vol = <>; sensor1_dvdd-supply = <>; sensor1_dvdd_vol = <>; sensor1_power_en = <>; sensor1_reset = <&pio PK 10 GPIO_ACTIVE_LOW>; sensor1_pwdn = <>; status = "okay"; }; vinc00:vinc@5830000 { vinc0_csi_sel = <0>; vinc0_mipi_sel = <0>; vinc0_isp_sel = <4>; vinc0_isp_tx_ch = <0>; vinc0_tdm_rx_sel = <0>; vinc0_rear_sensor_sel = <0>; vinc0_front_sensor_sel = <0>; vinc0_sensor_list = <0>; device_id = <0>; work_mode = <0x0>; status = "okay"; }; vinc01:vinc@582fffc { vinc1_csi_sel = <1>; vinc1_mipi_sel = <2>; vinc1_isp_sel = <1>; vinc1_isp_tx_ch = <0>; vinc1_tdm_rx_sel = <1>; vinc1_rear_sensor_sel = <1>; vinc1_front_sensor_sel = <1>; vinc1_sensor_list = <0>; device_id = <1>; status = "disabled"; }; vinc02:vinc@582fff8 { vinc2_csi_sel = <2>; vinc2_mipi_sel = <0xff>; vinc2_isp_sel = <2>; vinc2_isp_tx_ch = <2>; vinc2_tdm_rx_sel = <2>; vinc2_rear_sensor_sel = <0>; vinc2_front_sensor_sel = <0>; vinc2_sensor_list = <0>; device_id = <2>; status = "disabled"; }; vinc03:vinc@582fff4 { vinc3_csi_sel = <0>; vinc3_mipi_sel = <0xff>; vinc3_isp_sel = <0>; vinc3_isp_tx_ch = <0>; vinc3_tdm_rx_sel = <0>; vinc3_rear_sensor_sel = <1>; vinc3_front_sensor_sel = <1>; vinc3_sensor_list = <0>; device_id = <3>; status = "disabled"; }; vinc10:vinc@5831000 { vinc4_csi_sel = <0>; vinc4_mipi_sel = <0>; vinc4_isp_sel = <4>; vinc4_isp_tx_ch = <1>; vinc4_tdm_rx_sel = <0>; vinc4_rear_sensor_sel = <0>; vinc4_front_sensor_sel = <0>; vinc4_sensor_list = <0>; device_id = <4>; work_mode = <0x0>; status = "okay"; }; vinc11:vinc@5830ffc { vinc5_csi_sel = <2>; vinc5_mipi_sel = <0xff>; vinc5_isp_sel = <1>; vinc5_isp_tx_ch = <1>; vinc5_tdm_rx_sel = <1>; vinc5_rear_sensor_sel = <0>; vinc5_front_sensor_sel = <0>; vinc5_sensor_list = <0>; device_id = <5>; status = "disabled"; }; vinc12:vinc@5830ff8 { vinc6_csi_sel = <2>; vinc6_mipi_sel = <0xff>; vinc6_isp_sel = <0>; vinc6_isp_tx_ch = <0>; vinc6_tdm_rx_sel = <0>; vinc6_rear_sensor_sel = <0>; vinc6_front_sensor_sel = <0>; vinc6_sensor_list = <0>; device_id = <6>; status = "disabled"; }; vinc13:vinc@5830ff4 { vinc7_csi_sel = <2>; vinc7_mipi_sel = <0xff>; vinc7_isp_sel = <0>; vinc7_isp_tx_ch = <0>; vinc7_tdm_rx_sel = <0>; vinc7_rear_sensor_sel = <0>; vinc7_front_sensor_sel = <0>; vinc7_sensor_list = <0>; device_id = <7>; status = "disabled"; }; vinc20:vinc@5832000 { vinc8_csi_sel = <0>; vinc8_mipi_sel = <0>; vinc8_isp_sel = <4>; vinc8_isp_tx_ch = <2>; vinc8_tdm_rx_sel = <0>; vinc8_rear_sensor_sel = <0>; vinc8_front_sensor_sel = <0>; vinc8_sensor_list = <0>; device_id = <8>; work_mode = <0x0>; status = "okay"; }; vinc21:vinc@5831ffc { vinc9_csi_sel = <2>; vinc9_mipi_sel = <0xff>; vinc9_isp_sel = <0>; vinc9_isp_tx_ch = <0>; vinc9_tdm_rx_sel = <0>; vinc9_rear_sensor_sel = <0>; vinc9_front_sensor_sel = <0>; vinc9_sensor_list = <0>; device_id = <9>; status = "disabled"; }; vinc22:vinc@5831ff8 { vinc10_csi_sel = <2>; vinc10_mipi_sel = <0xff>; vinc10_isp_sel = <0>; vinc10_isp_tx_ch = <0>; vinc10_tdm_rx_sel = <0>; vinc10_rear_sensor_sel = <0>; vinc10_front_sensor_sel = <0>; vinc10_sensor_list = <0>; device_id = <10>; status = "disabled"; }; vinc23:vinc@5831ff4 { vinc11_csi_sel = <2>; vinc11_mipi_sel = <0xff>; vinc11_isp_sel = <0>; vinc11_isp_tx_ch = <0>; vinc11_tdm_rx_sel = <0>; vinc11_rear_sensor_sel = <0>; vinc11_front_sensor_sel = <0>; vinc11_sensor_list = <0>; device_id = <11>; status = "disabled"; }; vinc30:vinc@5833000 { vinc12_csi_sel = <0>; vinc12_mipi_sel = <0>; vinc12_isp_sel = <4>; vinc12_isp_tx_ch = <3>; vinc12_tdm_rx_sel = <0>; vinc12_rear_sensor_sel = <0>; vinc12_front_sensor_sel = <0>; vinc12_sensor_list = <0>; device_id = <12>; work_mode = <0x0>; status = "okay"; }; vinc31:vinc@5832ffc { vinc13_csi_sel = <2>; vinc13_mipi_sel = <0xff>; vinc13_isp_sel = <0>; vinc13_isp_tx_ch = <0>; vinc13_tdm_rx_sel = <0>; vinc13_rear_sensor_sel = <0>; vinc13_front_sensor_sel = <0>; vinc13_sensor_list = <0>; device_id = <13>; status = "disabled"; }; vinc32:vinc@5832ff8 { vinc14_csi_sel = <2>; vinc14_mipi_sel = <0xff>; vinc14_isp_sel = <0>; vinc14_isp_tx_ch = <0>; vinc14_tdm_rx_sel = <0>; vinc14_rear_sensor_sel = <0>; vinc14_front_sensor_sel = <0>; vinc14_sensor_list = <0>; device_id = <14>; status = "disabled"; }; vinc33:vinc@5832ff4 { vinc15_csi_sel = <2>; vinc15_mipi_sel = <0xff>; vinc15_isp_sel = <0>; vinc15_isp_tx_ch = <0>; vinc15_tdm_rx_sel = <0>; vinc15_rear_sensor_sel = <0>; vinc15_front_sensor_sel = <0>; vinc15_sensor_list = <0>; device_id = <15>; status = "disabled"; }; vinc40:vinc@5834000 { vinc16_csi_sel = <3>; vinc16_mipi_sel = <0xff>; vinc16_isp_sel = <5>; vinc16_isp_tx_ch = <0>; vinc16_tdm_rx_sel = <0>; vinc16_rear_sensor_sel = <1>; vinc16_front_sensor_sel = <1>; vinc16_sensor_list = <0>; device_id = <16>; status = "okay"; }; vinc50:vinc@5835000 { vinc17_csi_sel = <3>; vinc17_mipi_sel = <0xff>; vinc17_isp_sel = <5>; vinc17_isp_tx_ch = <1>; vinc17_tdm_rx_sel = <0>; vinc17_rear_sensor_sel = <1>; vinc17_front_sensor_sel = <1>; vinc17_sensor_list = <0>; device_id = <17>; status = "okay"; }; }; &twi6 { clock-frequency = <400000>; pinctrl-0 = <&s_twi0_pins_default>; pinctrl-1 = <&s_twi0_pins_sleep>; pinctrl-names = "default", "sleep"; device_type = "twi6"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; no_suspend = <1>; status = "okay"; tcs0: tcs@41 { compatible = "ext,tcs4838"; reg = <0x41>; status = "disabled"; tcs4838_delay = <0>; regulator1: regulators@1 { reg_tcs0: dcdc0 { regulator-name = "tcs4838-dcdc0"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; regulator-ramp-delay = <520>; regulator-enable-ramp-delay = <1000>; regulator-always-on; regulator-boot-on; }; reg_tcs1: dcdc1 { regulator-name = "tcs4838-dcdc1"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; regulator-ramp-delay = <520>; regulator-enable-ramp-delay = <1000>; }; }; virtual-ext-dcdc0 { compatible = "xpower-vregulator,ext-dcdc0"; dcdc0-supply = <®_tcs0>; }; virtual-ext-dcdc1 { compatible = "xpower-vregulator,ext-dcdc1"; dcdc1-supply = <®_tcs1>; }; }; sy0: sy@60 { compatible = "ext,sy8827g"; reg = <0x60>; status = "disabled"; sy8827g_delay = <0>; regulator2: regulators@2 { reg_sy0: dcdc0 { regulator-name = "sy8827g-dcdc0"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; regulator-ramp-delay = <520>; regulator-enable-ramp-delay = <1000>; regulator-always-on; regulator-boot-on; }; reg_sy1: dcdc1 { regulator-name = "sy8827g-dcdc1"; regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; regulator-ramp-delay = <520>; regulator-enable-ramp-delay = <1000>; }; }; virtual-ext-dcdc0 { compatible = "xpower-vregulator,ext-dcdc0"; dcdc0-supply = <®_sy0>; }; virtual-ext-dcdc1 { compatible = "xpower-vregulator,ext-dcdc1"; dcdc1-supply = <®_sy1>; }; }; axp1530: axp1530@36{ compatible = "ext,axp1530"; status = "okay"; reg = <0x36>; wakeup-source; regulators{ reg_ext_axp1530_dcdc1: dcdc1 { regulator-name = "axp1530-dcdc1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3400000>; regulator-step-delay-us = <25>; regulator-final-delay-us = <50>; regulator-always-on; }; reg_ext_axp1530_dcdc2: dcdc2 { regulator-name = "axp1530-dcdc2"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <1540000>; regulator-step-delay-us = <25>; regulator-final-delay-us = <50>; regulator-ramp-delay = <200>; /* FIXME */ regulator-always-on; }; reg_ext_axp1530_dcdc3: dcdc3 { regulator-name = "axp1530-dcdc3"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <1840000>; regulator-step-delay-us = <25>; regulator-final-delay-us = <50>; regulator-always-on; }; reg_ext_axp1530_aldo1: ldo1 { regulator-name = "axp1530-aldo1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-step-delay-us = <25>; regulator-final-delay-us = <50>; }; reg_ext_axp1530_dldo1: ldo2 { regulator-name = "axp1530-dldo1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-step-delay-us = <25>; regulator-final-delay-us = <50>; }; }; virtual-ext-dcdc1 { compatible = "xpower-vregulator,ext-dcdc1"; dcdc1-supply = <®_ext_axp1530_dcdc1>; }; virtual-ext-dcdc2 { compatible = "xpower-vregulator,ext-dcdc2"; dcdc2-supply = <®_ext_axp1530_dcdc2>; }; virtual-ext-dcdc3 { compatible = "xpower-vregulator,ext-dcdc3"; dcdc3-supply = <®_ext_axp1530_dcdc3>; }; virtual-ext-aldo1 { compatible = "xpower-vregulator,ext-aldo1"; aldo1-supply = <®_ext_axp1530_aldo1>; }; virtual-ext-dldo1 { compatible = "xpower-vregulator,ext-dldo1"; dldo1-supply = <®_ext_axp1530_dldo1>; }; }; pmu0: pmu@34 { compatible = "x-powers,axp2202"; reg = <0x34>; status = "okay"; interrupts = <0 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&nmi_intc>; x-powers,drive-vbus-en; pmu_reset = <0>; pmu_irq_wakeup = <1>; pmu_hot_shutdown = <1>; wakeup-source; usb_power_supply: usb_power_supply { compatible = "x-powers,axp2202-usb-power-supply"; status = "okay"; pmu_usbpc_vol = <4600>; pmu_usbpc_cur = <500>; pmu_usbad_vol = <4000>; pmu_usbad_cur = <2500>; pmu_usb_typec_used = <1>; wakeup_usb_in; wakeup_usb_out; det_acin_supply = <&gpio_power_supply>; pmu_acin_usbid_drv = <&pio PH 12 GPIO_ACTIVE_LOW>; pmu_vbus_det_gpio = <&pio PH 13 GPIO_ACTIVE_LOW>; }; gpio_power_supply: gpio_power_supply { compatible = "x-powers,gpio-supply"; status = "disabled"; pmu_acin_det_gpio = <&pio PH 14 GPIO_ACTIVE_LOW>; det_usb_supply = <&usb_power_supply>; }; bat_power_supply: bat-power-supply { compatible = "x-powers,axp2202-bat-power-supply"; param = <&axp2202_parameter>; status = "disabled"; pmu_chg_ic_temp = <0>; pmu_battery_rdc= <170>; pmu_battery_cap = <5000>; pmu_runtime_chgcur = <1000>; pmu_suspend_chgcur = <1500>; pmu_shutdown_chgcur = <1500>; pmu_init_chgvol = <4350>; pmu_battery_warning_level1 = <15>; pmu_battery_warning_level2 = <0>; pmu_chgled_func = <0>; pmu_chgled_type = <0>; pmu_bat_para1 = <0>; pmu_bat_para2 = <0>; pmu_bat_para3 = <0>; pmu_bat_para4 = <0>; pmu_bat_para5 = <0>; pmu_bat_para6 = <0>; pmu_bat_para7 = <2>; pmu_bat_para8 = <3>; pmu_bat_para9 = <4>; pmu_bat_para10 = <6>; pmu_bat_para11 = <9>; pmu_bat_para12 = <14>; pmu_bat_para13 = <26>; pmu_bat_para14 = <38>; pmu_bat_para15 = <49>; pmu_bat_para16 = <52>; pmu_bat_para17 = <56>; pmu_bat_para18 = <60>; pmu_bat_para19 = <64>; pmu_bat_para20 = <70>; pmu_bat_para21 = <77>; pmu_bat_para22 = <83>; pmu_bat_para23 = <87>; pmu_bat_para24 = <90>; pmu_bat_para25 = <95>; pmu_bat_para26 = <99>; pmu_bat_para27 = <99>; pmu_bat_para28 = <100>; pmu_bat_para29 = <100>; pmu_bat_para30 = <100>; pmu_bat_para31 = <100>; pmu_bat_para32 = <100>; pmu_bat_temp_enable = <1>; pmu_jetia_en = <1>; pmu_bat_charge_ltf = <1695>; //-5 pmu_bat_charge_htf = <151>; //60 pmu_bat_shutdown_ltf = <2125>; //-10 pmu_bat_shutdown_htf = <131>; //65 pmu_jetia_cool = <1361>; //0 pmu_jetia_warm = <208>; //50 pmu_jcool_ifall = <0>;//100% pmu_jwarm_ifall = <0>;//100% pmu_bat_temp_para1 = <4378>; //Murata -25 pmu_bat_temp_para2 = <2682>; //-15 pmu_bat_temp_para3 = <2125>; //-10 pmu_bat_temp_para4 = <1695>; //-5 pmu_bat_temp_para5 = <1361>;//0 pmu_bat_temp_para6 = <1101>; //5 pmu_bat_temp_para7 = <896>; //10 pmu_bat_temp_para8 = <604>; //20 pmu_bat_temp_para9 = <416>; //30 pmu_bat_temp_para10 = <292>; //40 pmu_bat_temp_para11 = <246>; //45 pmu_bat_temp_para12 = <208>; //50 pmu_bat_temp_para13 = <177>; //55 pmu_bat_temp_para14 = <151>; //60 pmu_bat_temp_para15 = <111>; //70 pmu_bat_temp_para16 = <83>; //80 wakeup_bat_out; wakeup_new_soc; /* wakeup_bat_in; */ /* wakeup_bat_charging; */ /* wakeup_bat_charge_over; */ /* wakeup_low_warning1; */ /* wakeup_low_warning2; */ wakeup_bat_untemp_work; wakeup_bat_ovtemp_work; /* wakeup_bat_untemp_chg; */ /* wakeup_bat_ovtemp_chg; */ }; powerkey0: powerkey@0 { status = "okay"; compatible = "x-powers,axp2101-pek"; pmu_powkey_off_time = <6000>; pmu_powkey_off_func = <0>; pmu_powkey_off_en = <1>; pmu_powkey_long_time = <1500>; pmu_powkey_on_time = <512>; wakeup_rising; wakeup_falling; }; regulator0: regulators@0 { reg_dcdc1: dcdc1 { regulator-name = "axp2202-dcdc1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <1540000>; regulator-ramp-delay = <250>; regulator-enable-ramp-delay = <1000>; regulator-boot-on; regulator-always-on; }; reg_dcdc2: dcdc2 { regulator-name = "axp2202-dcdc2"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3400000>; regulator-ramp-delay = <250>; regulator-enable-ramp-delay = <1000>; regulator-boot-on; regulator-always-on; }; reg_dcdc3: dcdc3 { regulator-name = "axp2202-dcdc3"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <1840000>; regulator-ramp-delay = <250>; regulator-enable-ramp-delay = <1000>; regulator-always-on; }; reg_dcdc4: dcdc4 { regulator-name = "axp2202-dcdc4"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3700000>; regulator-ramp-delay = <250>; regulator-enable-ramp-delay = <1000>; }; reg_rtcldo: rtcldo { /* RTC_LDO is a fixed, always-on regulator */ regulator-name = "axp2202-rtcldo"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; regulator-always-on; }; reg_aldo1: aldo1 { regulator-name = "axp2202-aldo1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_aldo2: aldo2 { regulator-name = "axp2202-aldo2"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_aldo3: aldo3 { regulator-name = "axp2202-aldo3"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; regulator-always-on; regulator-boot-on; }; reg_aldo4: aldo4 { regulator-name = "axp2202-aldo4"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; regulator-always-on; regulator-boot-on; }; reg_bldo1: bldo1 { regulator-name = "axp2202-bldo1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_bldo2: bldo2 { regulator-name = "axp2202-bldo2"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; regulator-boot-on; regulator-always-on; }; reg_bldo3: bldo3 { regulator-name = "axp2202-bldo3"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_bldo4: bldo4 { regulator-name = "axp2202-bldo4"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_cldo1: cldo1 { regulator-name = "axp2202-cldo1"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_cldo2: cldo2 { regulator-name = "axp2202-cldo2"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; }; reg_cldo3: cldo3 { regulator-name = "axp2202-cldo3"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-ramp-delay = <2500>; regulator-enable-ramp-delay = <1000>; regulator-boot-on; regulator-always-on; }; reg_cldo4: cldo4 { regulator-name = "axp2202-cldo4"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <3500000>; regulator-enable-ramp-delay = <1000>; regulator-boot-on; regulator-always-on; }; reg_cpusldo: cpusldo { /* cpus */ regulator-name = "axp2202-cpusldo"; regulator-min-microvolt = <500000>; regulator-max-microvolt = <1400000>; regulator-boot-on; regulator-always-on; }; reg_vmid: vmid { regulator-name = "axp2202-vmid"; regulator-enable-ramp-delay = <1000>; }; reg_drivevbus: drivevbus { regulator-name = "axp2202-drivevbus"; regulator-enable-ramp-delay = <1000>; drivevbusin-supply = <®_vmid>; }; }; virtual-dcdc1 { compatible = "xpower-vregulator,dcdc1"; dcdc1-supply = <®_dcdc1>; }; virtual-dcdc2 { compatible = "xpower-vregulator,dcdc2"; dcdc2-supply = <®_dcdc2>; }; virtual-dcdc3 { compatible = "xpower-vregulator,dcdc3"; dcdc3-supply = <®_dcdc3>; }; virtual-dcdc4 { compatible = "xpower-vregulator,dcdc4"; dcdc4-supply = <®_dcdc4>; }; virtual-rtcldo { compatible = "xpower-vregulator,rtcldo"; rtcldo-supply = <®_rtcldo>; }; virtual-aldo1 { compatible = "xpower-vregulator,aldo1"; aldo1-supply = <®_aldo1>; }; virtual-aldo2 { compatible = "xpower-vregulator,aldo2"; aldo2-supply = <®_aldo2>; }; virtual-aldo3 { compatible = "xpower-vregulator,aldo3"; aldo3-supply = <®_aldo3>; }; virtual-aldo4 { compatible = "xpower-vregulator,aldo4"; aldo4-supply = <®_aldo4>; }; virtual-bldo1 { compatible = "xpower-vregulator,bldo1"; bldo1-supply = <®_bldo1>; }; virtual-bldo2 { compatible = "xpower-vregulator,bldo2"; bldo2-supply = <®_bldo2>; }; virtual-bldo3 { compatible = "xpower-vregulator,bldo3"; bldo3-supply = <®_bldo3>; }; virtual-bldo4 { compatible = "xpower-vregulator,bldo4"; bldo4-supply = <®_bldo4>; }; virtual-cldo1 { compatible = "xpower-vregulator,cldo1"; cldo1-supply = <®_cldo1>; }; virtual-cldo2 { compatible = "xpower-vregulator,cldo2"; cldo2-supply = <®_cldo2>; }; virtual-cldo3 { compatible = "xpower-vregulator,cldo3"; cldo3-supply = <®_cldo3>; }; virtual-cldo4 { compatible = "xpower-vregulator,cldo4"; cldo4-supply = <®_cldo4>; }; virtual-cpusldo { compatible = "xpower-vregulator,cpusldo"; cpusldo-supply = <®_cpusldo>; }; virtual-drivevbus { compatible = "xpower-vregulator,drivevbus"; drivevbus-supply = <®_drivevbus>; }; axp_gpio0: axp_gpio@0 { gpio-controller; #size-cells = <0>; #gpio-cells = <6>; status = "okay"; }; }; }; /{ axp2202_parameter:axp2202-parameter { select = "battery-model"; battery-model { parameter = /bits/ 8 <0x01 0xf5 0x40 0x00 0x1b 0x1e 0x28 0x0f 0x0c 0x1e 0x32 0x02 0x14 0x05 0x0a 0x04 0x74 0xfb 0xc8 0x0d 0x43 0x10 0xcc 0xfb 0x46 0x01 0xea 0x14 0x10 0x06 0xcc 0x06 0x9d 0x0b 0x63 0x0f 0xf4 0x0f 0x94 0x0a 0x4f 0x0e 0xf4 0x0e 0xeb 0x04 0xdd 0x04 0xd1 0x09 0xc7 0x0e 0xb9 0x0e 0xb6 0x09 0xae 0x0e 0x97 0x0e 0x97 0x04 0x86 0x04 0x73 0x09 0x69 0x0e 0x60 0x0e 0x1e 0x08 0x21 0x58 0x28 0x22 0x18 0x06 0x0d 0x01 0xc5 0x98 0x7e 0x66 0x4e 0x44 0x38 0x1a 0x12 0x0a 0xf6 0x00 0x00 0xf6 0x00 0xf6 0x00 0xfb 0x00 0x00 0xfb 0x00 0x00 0xfb 0x00 0x00 0xf6 0x00 0x00 0xf6 0x00 0xf6 0x00 0xfb 0x00 0x00 0xfb 0x00 0x00 0xfb 0x00 0x00 0xf6 0x00 0x00 0xf6 0x00 0xf6>; }; }; }; &twi7 { clock-frequency = <400000>; pinctrl-0 = <&s_twi1_pins_default>; pinctrl-1 = <&s_twi1_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_aldo3>; status = "disabled"; ac107: ac107@36 { #sound-dai-cells = <0>; compatible = "allwinner,sunxi-ac107"; reg = <0x36>; pllclk-src = "MCLK"; sysclk-src = "MCLK"; pcm-bit-first = "MSB"; frame-sync-width = <1>; rx-chmap = <0xaaaa>; ch1-dig-vol = <160>; ch2-dig-vol = <160>; ch1-pga-gain = <26>; ch2-pga-gain = <26>; status = "disabled"; }; }; &twi8 { clock-frequency = <400000>; pinctrl-0 = <&s_twi2_pins_default>; pinctrl-1 = <&s_twi2_pins_sleep>; pinctrl-names = "default", "sleep"; /* For stability and backwards compatibility, we recommend setting ‘twi_drv_used’ to 1 */ twi_drv_used = <1>; twi-supply = <®_aldo3>; status = "disabled"; }; &sdc2 { non-removable; bus-width = <8>; mmc-ddr-1_8v; mmc-hs200-1_8v; mmc-hs400-1_8v; no-sdio; no-sd; ctl-spec-caps = <0x308>; cap-mmc-highspeed; sunxi-power-save-mode; sunxi-dis-signal-vol-sw; mmc-bootpart-noacc; /*cap-hsq;*/ cqe-on; ctl-cmdq-md = <0x2>; max-frequency = <150000000>; vmmc-supply = <®_cldo3>; /*emmc io vol 3.3v*/ /*vqmmc-supply = <®_aldo1>;*/ /*emmc io vol 1.8v*/ vqmmc-supply = <®_cldo1>; status = "disabled"; }; &sdc0 { bus-width = <4>; cd-gpios = <&pio PF 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /*non-removable;*/ /*broken-cd;*/ /*cd-inverted*/ /*data3-detect;*/ /*card-pwr-gpios = <&pio PH 14 1 1 2 0xffffffff>;*/ cd-used-24M; cd-set-debounce = <0x1>; cap-sd-highspeed; sd-uhs-sdr50; sd-uhs-ddr50; sd-uhs-sdr104; no-sdio; no-mmc; sunxi-power-save-mode; /*sunxi-dis-signal-vol-sw;*/ max-frequency = <150000000>; ctl-spec-caps = <0x408>; sunxi-dly-208M = <0xff 1 0xff 0xff 0xff 0xff>; vmmc-supply = <®_cldo3>; vqmmc33sw-supply = <®_cldo3>; vdmmc33sw-supply = <®_cldo3>; vqmmc18sw-supply = <®_bldo3>; vdmmc18sw-supply = <®_bldo3>; status = "okay"; }; &sdc1 { bus-width = <4>; no-mmc; no-sd; cap-sd-highspeed; /*sd-uhs-sdr12*/ sd-uhs-sdr25; sd-uhs-sdr50; sd-uhs-ddr50; sd-uhs-sdr104; /*sunxi-power-save-mode;*/ sunxi-dis-signal-vol-sw; cap-sdio-irq; keep-power-in-suspend; ignore-pm-notify; max-frequency = <150000000>; ctl-spec-caps = <0x408>; status = "okay"; }; &nand0 { compatible = "allwinner,sun55iw3-nand"; device_type = "nand0"; //reg = <0x0 0x04011000 0x0 0x1000>;/* nand0 */ pinctrl-names = "default", "sleep"; pinctrl-0 = <&nand0_pins_default &nand0_pins_rb>; pinctrl-1 = <&nand0_pins_sleep>; nand0_regulator1 = "vcc-nand"; nand0_regulator2 = "none"; nand0_cache_level = <0x55aaaa55>; nand0_flush_cache_num = <0x55aaaa55>; nand0_capacity_level = <0x55aaaa55>; nand0_id_number_ctl = <0x55aaaa55>; nand0_print_level = <0x55aaaa55>; nand0_p0 = <0x55aaaa55>; nand0_p1 = <0x55aaaa55>; nand0_p2 = <0x55aaaa55>; nand0_p3 = <0x55aaaa55>; chip_code = "sun55iw3"; status = "disabled"; }; &rfkill { compatible = "allwinner,sunxi-rfkill"; chip_en; power_en; pinctrl-0; pinctrl-names; status = "okay"; /* wlan session */ wlan { compatible = "allwinner,sunxi-wlan"; clocks; clock-names; wlan_power = "axp2202-aldo3", "axp2202-bldo1"; /* vcc-pl/vcc-pg/vcc-pm */ wlan_power_vol= <3300000>, <1800000>; wlan_busnum = <0x1>; wlan_regon = <&r_pio PM 1 GPIO_ACTIVE_HIGH>; wlan_hostwake = <&r_pio PM 0 GPIO_ACTIVE_HIGH>; wakeup-source; }; /* bt session */ bt { compatible = "allwinner,sunxi-bt"; clocks; clock-names; bt_power = "axp2202-aldo3", "axp2202-bldo1"; /* vcc-pl/vcc-pg/vcc-pm */ bt_power_vol= <3300000>, <1800000>; bt_rst_n = <&r_pio PM 2 GPIO_ACTIVE_LOW>; }; }; &addr_mgt { compatible = "allwinner,sunxi-addr_mgt"; type_addr_wifi = <0x0>; type_addr_bt = <0x0>; type_addr_eth = <0x0>; status = "okay"; }; &btlpm { compatible = "allwinner,sunxi-btlpm"; uart_index = <0x1>; bt_wake = <&r_pio PM 3 GPIO_ACTIVE_HIGH>; bt_hostwake = <&r_pio PM 4 GPIO_ACTIVE_HIGH>; wakeup-source; status = "okay"; }; /* *usb_port_type: usb mode. 0-device, 1-host, 2-otg. *usb_detect_type: usb hotplug detect mode. 0-none, 1-vbus/id detect, 2-id/dpdm detect. *usb_detect_mode: 0-thread scan, 1-id gpio interrupt. *usb_id_gpio: gpio for id detect. *usb_det_vbus_gpio: gpio for id detect. gpio or "axp_ctrl"; *usb_wakeup_suspend:0-SUPER_STANDBY, 1-USB_STANDBY. */ &usbc0 { device_type = "usbc0"; usb_port_type = <0x2>; usb_detect_type = <0x1>; usb_detect_mode = <0x0>; usb_id_gpio = <&r_pio PL 10 GPIO_ACTIVE_HIGH>; enable-active-high; usb_det_vbus_gpio = <&r_pio PM 5 GPIO_ACTIVE_HIGH>; enable-active-high; detvbus_io-supply = <®_bldo1>; usb_regulator_io = "nocare"; usb_wakeup_suspend = <0>; usb_luns = <3>; usb_serial_unique = <0>; usb_serial_number = "20080411"; rndis_wceis = <1>; status = "okay"; }; &udc { det_vbus_supply = <&usb_power_supply>; phy_range = <0x153>; status = "okay"; }; &ehci0 { drvvbus-supply = <®_usb0_vbus>; phy_range = <0x153>; status = "okay"; }; &ohci0 { drvvbus-supply = <®_usb0_vbus>; phy_range = <0x153>; status = "okay"; }; &usbc1 { device_type = "usbc1"; usb_regulator_io = "nocare"; usb_wakeup_suspend = <0>; status = "okay"; }; &ehci1 { drvvbus-supply = <®_usb1_vbus>; phy_range = <0x153>; status = "okay"; }; &ohci1 { drvvbus-supply = <®_usb1_vbus>; phy_range = <0x153>; status = "okay"; }; &usbc2 { device_type = "usbc2"; drvvbus-supply = <®_usb1_vbus>; status = "okay"; }; &xhci2 { dr_mode = "host"; status = "okay"; }; &u2phy { status = "okay"; }; &combophy { resets = <&ccu RST_BUS_PCIE_USB3>; phy_use_sel = <1>; /* 0:PCIE; 1:USB3 */ status = "okay"; }; &gpu { gpu_idle = <1>; dvfs_status = <1>; mali-supply = <®_dcdc2>; }; /*---------------------------------------------------------------------------------- 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. ----------------------------------------------------------------------------------*/ &disp { disp_init_enable = <1>; disp_mode = <0>; screen0_output_type = <1>; screen0_output_mode = <4>; screen0_to_lcd_index = <0>; screen1_output_type = <3>; screen1_output_mode = <5>; screen1_to_lcd_index = <2>; screen1_output_format = <0>; screen1_output_bits = <0>; screen1_output_eotf = <4>; screen1_output_cs = <257>; screen1_output_dvi_hdmi = <2>; screen1_output_range = <2>; screen1_output_scan = <0>; screen1_output_aspect_ratio = <8>; dev0_output_type = <1>; dev0_output_mode = <4>; dev0_screen_id = <0>; dev0_do_hpd = <0>; dev1_output_type = <4>; dev1_output_mode = <10>; dev1_screen_id = <1>; dev1_do_hpd = <1>; def_output_dev = <0>; hdmi_mode_check = <1>; display_device_num = <3>; primary_display_type = "LCD"; primary_de_id = <0>; primary_framebuffer_width = <1280>; primary_framebuffer_height = <800>; primary_dpix = <213>; primary_dpiy = <213>; extend0_display_type = "HDMI"; extend0_de_id = <1>; extend0_framebuffer_width = <1920>; extend0_framebuffer_height = <1080>; extend0_dpix = <160>; extend0_dpiy = <160>; extend1_display_type = "DP"; extend1_de_id = <1>; extend1_framebuffer_width = <1920>; extend1_framebuffer_height = <1080>; extend1_dpix = <160>; extend1_dpiy = <160>; fb_format = <0>; fb_num = <2>; /*<disp channel layer zorder>*/ fb0_map = <0 1 0 16>; fb0_width = <1280>; fb0_height = <800>; /*<disp channel layer zorder>*/ fb1_map = <1 1 0 16>; fb1_width = <1920>; fb1_height = <1080>; /*<disp channel layer zorder>*/ fb2_map = <1 0 0 16>; fb2_width = <1280>; fb2_height = <720>; /*<disp channel layer zorder>*/ fb3_map = <1 1 0 16>; fb3_width = <300>; fb3_height = <300>; chn_cfg_mode = <3>; disp_para_zone = <1>; /* dual display clock constraints: 1. two tcons cannot share a parent clock. 2. when dsi uses ccu clock, combphy and corresponding tcon use the same parent clock. */ assigned-clocks = <&ccu CLK_DE>, <&ccu CLK_VO0_TCONLCD0>, <&ccu CLK_VO0_TCONLCD1>, <&ccu CLK_VO1_TCONLCD0>, <&ccu CLK_TCONTV>, <&ccu CLK_TCONTV1>, <&ccu CLK_COMBPHY0>, <&ccu CLK_COMBPHY1>, <&ccu CLK_DSI0>, <&ccu CLK_DSI1>, <&ccu CLK_EDP>; assigned-clock-parents = <&ccu CLK_PLL_VIDEO3_4X>, <&ccu CLK_PLL_VIDEO0_4X>, <&ccu CLK_PLL_VIDEO1_4X>, <&ccu CLK_PLL_VIDEO1_4X>, <&ccu CLK_PLL_VIDEO1_4X>, <&ccu CLK_PLL_VIDEO1_4X>, <&ccu CLK_PLL_VIDEO0_4X>, <&ccu CLK_PLL_VIDEO1_4X>, <&ccu CLK_PLL_PERI0_150M>, <&ccu CLK_PLL_PERI0_150M>, <&ccu CLK_PLL_VIDEO1_4X>; assigned-clock-rates = <600000000>; cldo3-supply = <®_cldo3>; dcdc4-supply = <®_dcdc4>; cldo1-supply = <®_cldo1>; pwms = <&pwm0 4 5000000 0>, <&pwm0 5 5000000 0>; pwm-names = "lvds0_backlight", "lvds2_backlight"; power-domains = <&pd1 A523_PCK_DE>, <&pd1 A523_PCK_VO0>, <&pd1 A523_PCK_VO1>; power-domain-names = "pd_de", "pd_vo0", "pd_vo1"; pinctrl-names = "active", "sleep"; pinctrl-0 = <&pwm0_0_pin_active>; pinctrl-1 = <&pwm0_0_pin_sleep>; }; #if 1 &lcd0 { lcd_used = <1>; lcd_driver_name = "bp101wx1"; lcd_backlight = <50>; lcd_if = <3>; lcd_x = <1280>; lcd_y = <800>; lcd_width = <150>; lcd_height = <94>; lcd_dclk_freq = <75>; lcd_pwm_used = <1>; lcd_pwm_ch = <4>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <0>; lcd_pwm_max_limit = <255>; lcd_pwm_name = "lvds0_backlight"; lcd_hbp = <88>; lcd_ht = <1451>; lcd_hspw = <18>; lcd_vbp = <23>; lcd_vt = <860>; lcd_vspw = <10>; lcd_lvds_if = <0>; lcd_lvds_colordepth = <0>; lcd_lvds_mode = <0>; lcd_frm = <0>; lcd_hv_clk_phase = <0>; lcd_hv_sync_polarity= <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; lcd_fsync_en = <0>; lcd_fsync_act_time = <1000>; lcd_fsync_dis_time = <1000>; lcd_fsync_pol = <0>; lcd_start_delay = <5>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; lcd_pin_power = "cldo3"; lcd_power = "dcdc4"; lcd_power1 = "cldo1"; lcd_gpio_0 = <&pio PI 2 GPIO_ACTIVE_HIGH>; //reset lcd_bl_en = <&pio PI 2 GPIO_ACTIVE_HIGH>; pinctrl-0 = <&lvds0_pins_a>; pinctrl-1 = <&lvds0_pins_b>; lvds0_pinctrl-0 = <&lvds0_pins_a>; lvds0_pinctrl-1 = <&lvds0_pins_b>; lvds1_pinctrl-0 = <&lvds1_pins_a>; lvds1_pinctrl-1 = <&lvds1_pins_b>; dsi0_pinctrl-0 = <&dsi0_4lane_pins_a>; dsi0_pinctrl-1 = <&dsi0_4lane_pins_b>; dual_dsi_pinctrl-0 = <&dsi0_4lane_pins_a>, <&dsi1_4lane_pins_a>; dual_dsi_pinctrl-1 = <&dsi0_4lane_pins_b>, <&dsi1_4lane_pins_b>; dual_lvds0_pinctrl-0 = <&lvds0_pins_a>, <&lvds1_pins_a>; dual_lvds0_pinctrl-1 = <&lvds0_pins_b>, <&lvds1_pins_b>; }; #else &lcd0 { /* dual-lvds */ lcd_used = <1>; status = "okay"; lcd_driver_name = "default_lcd"; lcd_backlight = <50>; lcd_if = <3>; lcd_x = <1920>; lcd_y = <1080>; lcd_width = <476>; lcd_height = <268>; lcd_dclk_freq = <149>; lcd_pwm_used = <1>; lcd_pwm_ch = <4>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <0>; lcd_pwm_max_limit = <255>; lcd_pwm_name = "lvds0_backlight"; lcd_hbp = <148>; lcd_ht = <2200>; lcd_hspw = <44>; lcd_vbp = <36>; lcd_vt = <1125>; lcd_vspw = <5>; lcd_lvds_if = <1>; lcd_lvds_colordepth = <0>; lcd_lvds_mode = <0>; lcd_frm = <0>; lcd_hv_clk_phase = <0>; lcd_hv_sync_polarity= <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; lcd_fsync_en = <0>; lcd_fsync_act_time = <1000>; lcd_fsync_dis_time = <1000>; lcd_fsync_pol = <0>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; lcd_power = "dcdc4"; lcd_power1 = "cldo1"; lcd_bl_en = <&pio PI 2 GPIO_ACTIVE_HIGH>; pinctrl-0 = <&lvds0_pins_a>, <&lvds1_pins_a>; pinctrl-1 = <&lvds0_pins_b>, <&lvds1_pins_b>; }; #endif #if 1 &lcd1 { lcd_used = <1>; status = "okay"; lcd_driver_name = "SQ101D_Q5DI404_84H501"; lcd_backlight = <200>; lcd_if = <4>; lcd_x = <1200>; lcd_y = <1920>; lcd_width = <136>; lcd_height = <217>; lcd_dclk_freq = <157>; lcd_pwm_used = <1>; lcd_pwm_ch = <0>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <0>; lcd_pwm_max_limit = <255>; lcd_hbp = <50>; lcd_ht = <1330>; lcd_hspw = <10>; lcd_vbp = <20>; lcd_vt = <1960>; lcd_vspw = <4>; lcd_frm = <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; lcd_start_delay = <5>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; lcd_dsi_if = <0>; lcd_dsi_lane = <4>; lcd_dsi_format = <0>; lcd_dsi_te = <0>; lcd_dsi_eotp = <0>; lcd_power1 = "cldo4"; lcd_power2 = "cldo1"; // lcd_gpio_2 = <&pio PD 22 GPIO_ACTIVE_HIGH>; //reset pinctrl-0 = <&dsi1_4lane_pins_a>; pinctrl-1 = <&dsi1_4lane_pins_b>; // lcd_bl_en = <&pio PH 16 GPIO_ACTIVE_HIGH>; lcd_bl_0_percent = <5>; }; #else &lcd1 { lcd_used = <1>; lcd_driver_name = "default_lcd"; lcd_backlight = <50>; lcd_if = <0>; lcd_x = <800>; lcd_y = <480>; lcd_width = <150>; lcd_height = <94>; lcd_dclk_freq = <48>; lcd_pwm_used = <1>; lcd_pwm_ch = <7>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <0>; lcd_hbp = <55>; lcd_ht = <1240>; lcd_hspw = <20>; lcd_vbp = <35>; lcd_vt = <650>; lcd_vspw = <10>; lcd_lvds_if = <0>; lcd_lvds_colordepth = <1>; lcd_lvds_mode = <0>; lcd_frm = <1>; lcd_io_phase = <0x0000>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; }; #endif &lcd2 { lcd_used = <0>; lcd_driver_name = "bp101wx1"; lcd_backlight = <50>; lcd_if = <3>; lcd_x = <1280>; lcd_y = <800>; lcd_width = <150>; lcd_height = <94>; lcd_dclk_freq = <75>; lcd_pwm_used = <1>; lcd_pwm_ch = <5>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <0>; lcd_pwm_max_limit = <255>; lcd_pwm_name = "lvds2_backlight"; lcd_hbp = <88>; lcd_ht = <1451>; lcd_hspw = <18>; lcd_vbp = <23>; lcd_vt = <860>; lcd_vspw = <10>; lcd_lvds_if = <0>; lcd_lvds_colordepth = <0>; lcd_lvds_mode = <0>; lcd_frm = <0>; lcd_hv_clk_phase = <0>; lcd_hv_sync_polarity= <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; lcd_fsync_en = <0>; lcd_fsync_pol = <0>; lcd_start_delay = <5>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; lcd_pin_power = "cldo3"; lcd_power = "dcdc4"; /* lvds_power & other interface power */ lcd_bl_en = <&pio PI 5 GPIO_ACTIVE_HIGH>; pinctrl-0 = <&lvds2_pins_a>; pinctrl-1 = <&lvds2_pins_b>; lvds2_pinctrl-0 = <&lvds2_pins_a>; lvds2_pinctrl-1 = <&lvds2_pins_b>; lvds3_pinctrl-0 = <&lvds3_pins_a>; lvds3_pinctrl-1 = <&lvds3_pins_b>; dual_lvds1_pinctrl-0 = <&lvds2_pins_a>, <&lvds3_pins_a>; dual_lvds1_pinctrl-1 = <&lvds2_pins_b>, <&lvds3_pins_b>; }; &edp0 { // use if hardware reset pin is need /* edp_hw_reset_pin = <&pio PH XX GPIO_ACTIVE_LOW>; */ edp_ssc_en = <0>; edp_ssc_mode = <0>; edp_psr_support = <0>; edp_colordepth = <8>; /* 6/8/10/12/16 */ edp_color_fmt = <0>; /* 0:RGB 1: YUV444 2: YUV422 */ lane0_sw = <0>; lane0_pre = <0>; lane1_sw = <0>; lane1_pre = <0>; lane2_sw = <0>; lane2_pre = <0>; lane3_sw = <0>; lane3_pre = <0>; efficient_training = <0>; sink_capacity_prefer = <1>; edid_timings_prefer = <1>; timings_fixed = <1>; edp_panel_used = <1>; edp_panel_driver = "general_panel"; edp_bl_en = <&pio PI 5 GPIO_ACTIVE_HIGH>; edp_pwm_used = <1>; edp_pwm_ch = <5>; edp_pwm_freq = <50000>; edp_pwm_pol = <0>; edp_default_backlight = <200>; edp_panel_power_0 = "edp-panel"; vcc-edp-supply = <®_bldo3>; vdd-edp-supply = <®_dcdc2>; edp-panel-supply = <®_dcdc4>; status = "disabled"; }; &ve { ve-supply = <®_dcdc2>; enable_setup_ve_freq = <0>; /* default disable */ ve_freq_value = <624>; /* setup to 624MHz */ }; /* audio dirver module -> audio codec */ &codec { tx-hub-en; rx-sync-en; dac-vol = <63>; /* default value:63 range:0->63 */ dacl-vol = <160>; /* default value:160 range:0->255 */ dacr-vol = <160>; /* default value:160 range:0->255 */ adc1-vol = <160>; /* default value:160 range:0->255 */ adc2-vol = <160>; /* default value:160 range:0->255 */ adc3-vol = <160>; /* default value:160 range:0->255 */ lineout-gain = <31>; /* default value:31 range:0->31 */ hpout-gain = <7>; /* default value:7 range:0->7 */ adc1-gain = <31>; /* default value:31 range:0->31 */ adc2-gain = <31>; /* default value:31 range:0->31 */ adc3-gain = <31>; /* default value:31 range:0->31 */ /* to do: avcc-1.8 vdd33-3.3 cpvin-1.8 */ avcc-external; avcc-supply = <®_aldo4>; avcc-vol = <1800000>; vdd-external; vdd-supply = <®_cldo3>; vdd-vol = <3300000>; cpvin-external; cpvin-supply = <®_bldo3>; cpvin-vol = <1800000>; pa-pin-max = <1>; pa-pin-0 = <&r_pio PL 7 GPIO_ACTIVE_HIGH>; pa-pin-level-0 = <1>; pa-pin-msleep-0 = <0>; jack-det-level = <0>; jack-det-threshold = <8>; jack-det-debouce-time = <250>; /* extcon = <&usb_power_supply>; * jack-swpin-mic-sel = <&pio PH 8 GPIO_ACTIVE_HIGH>; * jack-swpin-hp-en = <&pio PH 15 GPIO_ACTIVE_HIGH>; * jack-swpin-hp-sel = <&pio PH 11 GPIO_ACTIVE_HIGH>; * jack-swmode-hp-off = <0x00>; * jack-swmode-hp-usb = <0x11>; * jack-swmode-hp-audio = <0x10>; * jack-det-level = <1>; * jack-det-threshold = <8>; * jack-det-debouce-time = <250>; */ status = "okay"; }; &codec_plat { status = "okay"; }; &codec_mach { soundcard-mach,jack-support = <1>; status = "okay"; soundcard-mach,cpu { sound-dai = <&codec_plat>; }; soundcard-mach,codec { sound-dai = <&codec>; }; }; &hdmi_codec { extcon = <&hdmi>; status = "okay"; }; &edp_codec { status = "disabled"; }; /* audio dirver module -> owa */ &owa_plat { pinctrl-used; pinctrl-names = "default","sleep"; pinctrl-0 = <&owa_pins_a>; pinctrl-1 = <&owa_pins_b>; tx-hub-en; status = "okay"; }; &owa_mach { status = "okay"; soundcard-mach,cpu { sound-dai = <&owa_plat>; }; soundcard-mach,codec { }; }; /* audio dirver module -> DMIC */ &dmic_plat { rx-chmap = <0x76543210>; data-vol = <0xB0>; rxdelaytime = <0>; /* pinctrl-used; */ /* pinctrl-names = "default","sleep"; */ /* pinctrl-0 = <&dmic_pins_a>; */ /* pinctrl-1 = <&dmic_pins_b>; */ rx-sync-en; status = "disabled"; }; &dmic_mach { status = "disabled"; soundcard-mach,cpu { sound-dai = <&dmic_plat>; }; soundcard-mach,codec { }; }; /* audio dirver module -> I2S/PCM */ &i2s0_plat { tdm-num = <0>; tx-pin = <0>; rx-pin = <0>; pinctrl-used; pinctrl-names = "default","sleep"; pinctrl-0 = <&i2s0_pins_a &i2s0_pins_c &i2s0_pins_d>; pinctrl-1 = <&i2s0_pins_b>; tx-hub-en; rx-sync-en; status = "okay"; }; &i2s0_mach { soundcard-mach,format = "i2s"; soundcard-mach,frame-master = <&i2s0_cpu>; soundcard-mach,bitclock-master = <&i2s0_cpu>; /* soundcard-mach,frame-inversion; */ /* soundcard-mach,bitclock-inversion; */ soundcard-mach,slot-num = <2>; soundcard-mach,slot-width = <32>; soundcard-mach,capture-only; status = "okay"; i2s0_cpu: soundcard-mach,cpu { sound-dai = <&i2s0_plat>; /* note: pll freq = 24.576M or 22.5792M * pll-fs */ soundcard-mach,pll-fs = <1>; /* note: * mclk freq = mclk-fs * 12.288M or 11.2896M (when mclk-fp ture) * mclk freq = mclk-fs * pcm rate (when mclk-fp false) */ soundcard-mach,mclk-fp; soundcard-mach,mclk-fs = <1>; }; i2s0_codec: soundcard-mach,codec { sound-dai = <&ac107>; soundcard-mach,pll-fs = <1>; }; }; &i2s1_plat { tdm-num = <1>; tx-pin = <0>; rx-pin = <0>; /* pinctrl-used; */ /* pinctrl-names= "default","sleep"; */ /* pinctrl-0 = <&i2s1_pins_a &i2s1_pins_c &i2s1_pins_d>; */ /* pinctrl-1 = <&i2s1_pins_b>; */ tx-hub-en; rx-sync-en; status = "disabled"; }; &i2s1_mach { soundcard-mach,format = "i2s"; soundcard-mach,frame-master = <&i2s1_cpu>; soundcard-mach,bitclock-master = <&i2s1_cpu>; /* soundcard-mach,frame-inversion; */ /* soundcard-mach,bitclock-inversion; */ soundcard-mach,slot-num = <2>; soundcard-mach,slot-width = <32>; status = "disabled"; i2s1_cpu: soundcard-mach,cpu { sound-dai = <&i2s1_plat>; soundcard-mach,pll-fs = <1>; soundcard-mach,mclk-fs = <0>; }; i2s1_codec: soundcard-mach,codec { }; }; &i2s2_plat { tdm-num = <2>; tx-pin = <0 1 2 3>; /* e.g. * tx-pin0-map0 = <0xFEDC3210> -> tx_pin_map[0][0] (Dout0-slot[7:0] map channel[15:12, 3:0]) * tx-pin0-map1 = <0x3210FEDC> -> tx_pin_map[0][1] (Dout0-slot[15:8] map channel[3:0, 15:12]) * tx-pin1-map0 = <0x76543210> -> tx_pin_map[1][0] (Dout1-slot[7:0] map channel[7:0]) */ tx-pin0-map0 = <0x76543210>; tx-pin0-map1 = <0xFEDCBA98>; tx-pin1-map0 = <0x76543210>; tx-pin1-map1 = <0xFEDCBA98>; tx-pin2-map0 = <0x76543210>; tx-pin2-map1 = <0xFEDCBA98>; tx-pin3-map0 = <0x76543210>; tx-pin3-map1 = <0xFEDCBA98>; rx-pin = <0>; /* pinctrl-used; */ /* pinctrl-names= "default","sleep"; */ /* pinctrl-0 = <&i2s2_pins_a &i2s2_pins_c &i2s2_pins_d &i2s2_pins_e>; */ /* pinctrl-1 = <&i2s2_pins_b>; */ tx-hub-en; rx-sync-en; /* edp not need dai-type */ dai-type = "hdmi"; status = "okay"; }; &i2s2_mach { soundcard-mach,format = "i2s"; soundcard-mach,frame-master = <&i2s2_cpu>; soundcard-mach,bitclock-master = <&i2s2_cpu>; /* soundcard-mach,frame-inversion; */ /* soundcard-mach,bitclock-inversion; */ soundcard-mach,slot-num = <2>; soundcard-mach,slot-width = <32>; soundcard-mach,playback-only; status = "okay"; i2s2_cpu: soundcard-mach,cpu { sound-dai = <&i2s2_plat>; soundcard-mach,pll-fs = <1>; /* edp mclk: 512fs */ soundcard-mach,mclk-fs = <0>; }; i2s2_codec: soundcard-mach,codec { sound-dai = <&hdmi_codec>; }; }; &i2s3_plat { tdm-num = <3>; tx-pin = <0>; rx-pin = <0>; /* pinctrl-used; */ /* pinctrl-names= "default","sleep"; */ /* pinctrl-0 = <&i2s3_pins_a &i2s3_pins_c &i2s3_pins_d>; */ /* pinctrl-1 = <&i2s3_pins_b>; */ tx-hub-en; rx-sync-en; status = "disabled"; }; &i2s3_mach { soundcard-mach,format = "i2s"; soundcard-mach,frame-master = <&i2s3_cpu>; soundcard-mach,bitclock-master = <&i2s3_cpu>; /* soundcard-mach,frame-inversion; */ /* soundcard-mach,bitclock-inversion; */ soundcard-mach,slot-num = <2>; soundcard-mach,slot-width = <32>; status = "disabled"; i2s3_cpu: soundcard-mach,cpu { sound-dai = <&i2s3_plat>; soundcard-mach,pll-fs = <1>; soundcard-mach,mclk-fs = <0>; }; i2s3_codec: soundcard-mach,codec { }; }; &hdmi { hdmi_used = <1>; bldo3-supply = <®_bldo3>; hdmi_power0 = "bldo3"; hdmi_power_cnt = <1>; hdmi_hdcp_enable = <1>; hdmi_hdcp22_enable = <0>; hdmi_cts_compatibility = <0>; hdmi_cec_support = <1>; hdmi_cec_super_standby = <1>; hdmi_skip_bootedid = <1>; ddc_en_io_ctrl = <0>; power_io_ctrl = <0>; status = "okay"; }; &cpu0 { cpu-supply = <®_dcdc1>; }; &dsufreq { dsu-supply = <®_dcdc1>; }; &mdio0 { status = "okay"; gmac0_phy0: ethernet-phy@1 { reset-gpios = <&pio PH 8 GPIO_ACTIVE_LOW>; }; }; &gmac0 { phy-mode = "rgmii"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&gmac0_pins_default>; pinctrl-1 = <&gmac0_pins_sleep>; sunxi,phy-clk-type = <0>; tx-delay = <3>; rx-delay = <4>; gmac3v3-supply = <®_cldo4>; status = "okay"; }; &gmac1 { phy-mode = "rgmii"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&gmac1_pins_default>; pinctrl-1 = <&gmac1_pins_sleep>; aw,soc-phy25m; tx-delay = <3>; rx-delay = <4>; dwmac3v3-supply = <®_cldo4>; status = "okay"; mdio1: mdio1@1 { gmac1_phy0: ethernet-phy@1 { reset-gpios = <&pio PI 5 GPIO_ACTIVE_LOW>; }; }; }; &npu { npu-supply = <®_ext_axp1530_dcdc3>; status = "okay"; }; &dram { dram_para00 = <0x00000000>; dram_para01 = <0x00000000>; dram_para02 = <0x00000000>; dram_para03 = <0x00000000>; dram_para04 = <0x00000000>; dram_para05 = <0x00000000>; dram_para06 = <0x00000000>; dram_para07 = <0x00000000>; dram_para08 = <0x00000000>; dram_para09 = <0x00000000>; dram_para10 = <0x00000000>; dram_para11 = <0x00000000>; dram_para12 = <0x00000000>; dram_para13 = <0x00000000>; dram_para14 = <0x00000000>; dram_para15 = <0x00000000>; dram_para16 = <0x00000000>; dram_para17 = <0x00000000>; dram_para18 = <0x00000000>; dram_para19 = <0x00000000>; dram_para20 = <0x00000000>; dram_para21 = <0x00000000>; dram_para22 = <0x00000000>; dram_para23 = <0x00000000>; dram_para24 = <0x00000000>; dram_para25 = <0x00000000>; dram_para26 = <0x00000000>; dram_para27 = <0x00000000>; dram_para28 = <0x00000000>; dram_para29 = <0x00000000>; dram_para30 = <0x00000000>; dram_para31 = <0x00000000>; dram_para32 = <0x00000000>; dram_para33 = <0x00000000>; dram_para34 = <0x00000000>; dram_para35 = <0x00000000>; dram_para36 = <0x00000000>; dram_para37 = <0x00000000>; dram_para38 = <0x00000000>; dram_para39 = <0x00000000>; dram_para40 = <0x00000000>; dram_para41 = <0x00000000>; dram_para42 = <0x00000000>; dram_para43 = <0x00000000>; dram_para44 = <0x00000000>; dram_para45 = <0x00000000>; dram_para46 = <0x00000000>; dram_para47 = <0x00000000>; dram_para48 = <0x00000000>; dram_para49 = <0x00000000>; dram_para50 = <0x00000000>; dram_para51 = <0x00000000>; dram_para52 = <0x00000000>; dram_para53 = <0x00000000>; dram_para54 = <0x00000000>; dram_para55 = <0x00000000>; dram_para56 = <0x00000000>; dram_para57 = <0x00000000>; dram_para58 = <0x00000000>; dram_para59 = <0x00000000>; dram_para60 = <0x00000000>; dram_para61 = <0x00000000>; dram_para62 = <0x00000000>; dram_para63 = <0x00000000>; dram_para64 = <0x00000000>; dram_para65 = <0x00000000>; dram_para66 = <0x00000000>; dram_para67 = <0x00000000>; dram_para68 = <0x00000000>; dram_para69 = <0x00000000>; dram_para70 = <0x00000000>; dram_para71 = <0x00000000>; dram_para72 = <0x00000000>; dram_para73 = <0x00000000>; dram_para74 = <0x00000000>; dram_para75 = <0x00000000>; dram_para76 = <0x00000000>; dram_para77 = <0x00000000>; dram_para78 = <0x00000000>; dram_para79 = <0x00000000>; dram_para80 = <0x00000000>; dram_para81 = <0x00000000>; dram_para82 = <0x00000000>; dram_para83 = <0x00000000>; dram_para84 = <0x00000000>; dram_para85 = <0x00000000>; dram_para86 = <0x00000000>; dram_para87 = <0x00000000>; dram_para88 = <0x00000000>; dram_para89 = <0x00000000>; dram_para90 = <0x00000000>; dram_para91 = <0x00000000>; dram_para92 = <0x00000000>; dram_para93 = <0x00000000>; dram_para94 = <0x00000000>; dram_para95 = <0x00000000>; }; &cpul_thermal_zone { cpul_trips: trips { cpul_crit: cpu_crit@0 { temperature = <115000>; type = "critical"; hysteresis = <0>; }; }; }; &cpub_thermal_zone { cpub_trips: trips { cpub_crit: cpu_crit@0 { temperature = <115000>; type = "critical"; hysteresis = <0>; }; }; }; &gpu_thermal_zone { gpu_trips: trips { gpu_crit: gpu_crit@0 { temperature = <115000>; type = "critical"; hysteresis = <0>; }; }; };
-
回复: R128 WIFI AP模式获取连接设备的IP地址的问题
wifi_ap_get_config(wifi_ap_config_t * ap_config)
可以参考
wifi ‑l
的实现 -
回复: 求指导,T113-S3 tinasdk如何配置板子启动后以太网自动启动和获取Ip
target/allwinner/t113-xxxxx/busybox-init-base-files/etc/init.d/rc.final
末尾加上
ifconfig eth0 up
udhcpc -i eth0 -
回复: V851S上的ISP真的坏了吗?
@kanken6174 TinyVision 制作的高清 1080P USB 摄像头
https://bbs.aw-ol.com/topic/5030/share/1 -
回复: D1s RGB屏线 定义无法修改!布线要小心!!!
如果需要整组红、蓝交换有一个配置:
lcd_rb_swap
这个配置会修改送到RGB的图像的RGB顺序
但是RGB输出的Pin是不能随意修改MUX的,例如不能修改为R[0]B[0]G[0]R[1]B[1]G[1] 排布
-
回复: 问下大家camerademo抓的是原图还是ISP调色过的图呢
Tina SDK 内置一个 libAWispApi 的包,支持在用户层对接 ISP,但是很可惜这个包没有适配 V85x 系列,这里就需要自行适配。其实适配很简单,SDK 已经提供了 lib 只是没提供编译支持。我们需要加上这个支持。
前往 openwrt/package/allwinner/vision/libAWIspApi/machinfo 文件夹中,新建一个文件夹 v851s ,然后新建文件 build.mk 写入如下配置:
ISP_DIR:=isp600
对于 v851se,v853 也可以这样操作,然后 m menuconfig 勾选上这个包
-
回复: 编译报错 libgettextlib.la failed
Ubuntu 22.04 / 20.04
更新软件源,更新系统软件包sudo apt-get update
sudo apt-get upgrade -y
安装开发依赖sudo apt-get install build-essential subversion git libncurses5-dev zlib1g-dev gawk flex bison quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip lsof
安装相关工具sudo apt-get install kconfig-frontends android-tools-mkbootimg python2 libpython3-dev
增加架构支持sudo dpkg --add-architecture i386
sudo apt-get update
安装支持包sudo apt install gcc-multilib
sudo apt install libc6:i386 libstdc++6:i386 lib32z1
Ubuntu 18.04
更新软件源,更新系统软件包sudo apt-get update
sudo apt-get upgrade -y
安装开发依赖sudo apt-get install build-essential subversion git libncurses5-dev zlib1g-dev gawk flex bison quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip lsof
安装相关工具sudo apt-get install android-tools-mkbootimg libpython3-dev
增加架构支持sudo dpkg --add-architecture i386
sudo apt-get update
安装支持包sudo apt install gcc-multilib
sudo apt install libc6:i386 libstdc++6:i386 lib32z1
Arch Linux / Manjaro
更新软件源,更新系统软件包pacman -Syyuu
安装开发依赖pacman -S --needed base-devel autoconf automake bash binutils bison bzip2 fakeroot file findutils flex gawk gcc gettext git grep groff gzip time unzip util-linux wget which zlib asciidoc help2man intltool perl-extutils-makemaker swig
安装相关工具pacman -S --needed libelf libtool libxslt m4 make ncurses openssl patch pkgconf python rsync sed texinfo
增加架构支持pacman -S --needed multilib-devel
CentOS / Fedora / openEulersudo dnf --setopt install_weak_deps=False --skip-broken install bash-completion bzip2 gcc gcc-c++ git make ncurses-devel patch rsync tar unzip wget which diffutils python2 python3 perl-base perl-Data-Dumper perl-File-Compare perl-File-Copy perl-FindBin perl-Thread-Queue glibc.i686
openSUSEsudo zypper install --no-recommends asciidoc bash bc binutils bzip2 fastjar flex gawk gcc
-
回复: 求教使用百问网v851s的sdk打包问题!
拉取SDK看了下,他默认配置是MBR格式,针对 NAND 设备。使用 PhoenixSuit 烧写的时候会自动识别存储器来判断使用GPT分区表还是MBR分区表。但是 PhoenixCard 刷写的时候无法识别到存储器,所以需要固件配置 GPT 或者 MBR,配置文件为
image.cfg
,如果没有配置 GPT 固件使用 MBR 格式固件,会导致PhoenixCard 将 boot1被写入 8K 偏移位,8K偏移位置正好是 GPT 分区表的位置,导致覆盖了 GPT 分区表,正确的操作应该是写入 128K 偏移,但是由于 SDK 内配置为MBR固件,而且PhoenixCard 无法读取目标设备是何种存储设备,所以PhoenixCard 默认写入 8K 偏移导致启动失败。修改方法如下
编辑文件:
device/config/chips/v851s/configs/default/image.cfg
加入一行,使打包成为 GPT 格式{filename = "sunxi_gpt.fex", maintype = "12345678", subtype = "1234567890___GPT",},
-
回复: V853和T527/A523疑问
两个芯片是不同的产品,V853面向的是视觉产品,注重编码性能,T527/A523面向泛平板,工控,屏控车载产品,注重解码性能,需要根据实际产品需求来选择芯片。
-
回复: 编译报错 libgettextlib.la failed
@cwj1986521 在 编译报错 libgettextlib.la failed 中说:
/usr/bin/ld: cannot find -lglib-2.0
/usr/bin/ld: cannot find -liconv
/usr/bin/ld: cannot find -lpcre目前编译的是安装在编译主机上的gettext,报错找不到链接库,需要安装 glib-2.0、iconv、pcre
-
回复: 烧录识别不了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
-
回复: 问下大家camerademo抓的是原图还是ISP调色过的图呢
camerademo 支持抓ISP后的图
勾选使用 VIN ISP 驱动即可
使用 ISP camerademo NV21 1920 1080 20 bmp /tmp 2
直接抓RAW:camerademo BGGR10 1920 1080 20 bmp /tmp 2
-
回复: 【T113 S3】【spi驱动】【DMA 连续内存分配】【dma_alloc_coherent】【失败】
#include "fsfpgain.h" static int fsfpgain_open(struct inode *inode, struct file *filp) { if (atomic_dec_and_test(&valid)) // 原子操作 唯一应用打开驱动 { return 0; } atomic_inc(&valid); return -EBUSY; } static int fsfpgain_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) {} static long fsfpgain_ioctl(struct file *file, uint32_t cmd, unsigned long arg) { } static int fsfpgain_mmap(struct file *filp, struct vm_area_struct *vma) { return 0; } static int fsfpgain_release(struct inode *inode, struct file *filp) { valid.counter = 1; // open函数访问,原子锁初始化 return 0; } static void init_p_buf_cut(void) {} static void spi_fpga_recv(struct buffer_cut *_p, int _no) {} static irqreturn_t irq_gpio_spi_handler(int irq, void *dev_id) {} static irqreturn_t irq_gpio_spi_thread_func(int irq, void *data) {} static const struct file_operations fsfpgain_fops = { .owner = THIS_MODULE, .open = fsfpgain_open, .read = fsfpgain_read, .release = fsfpgain_release, .unlocked_ioctl = fsfpgain_ioctl, .mmap = fsfpgain_mmap, }; static int fsfpgain_probe(struct spi_device *spi) { int ret = 0; valid.counter = 1; // open函数访问,原子锁初始化 // valid = ATOMIC_INIT(1); printk("fsfpgain_probe\r\n"); fsfpgaindev.major = 0; if (fsfpgaindev.major) { fsfpgaindev.devid = MKDEV(fsfpgaindev.major, 0); ret = register_chrdev_region(fsfpgaindev.devid, FSFPGAIN_CNT, FSFPGAIN_NAME); } else { ret = alloc_chrdev_region(&fsfpgaindev.devid, 0, FSFPGAIN_CNT, FSFPGAIN_NAME); fsfpgaindev.major = MAJOR(fsfpgaindev.devid); fsfpgaindev.minor = MINOR(fsfpgaindev.devid); } if (ret < 0) { printk("fsfpgain chrdev_region err!\r\n"); goto fail_devid; } printk("fsfpgain major=%d, minor=%d\r\n", fsfpgaindev.major, fsfpgaindev.minor); fsfpgaindev.cdev.owner = THIS_MODULE; /* 2、注册设备 */ cdev_init(&fsfpgaindev.cdev, &fsfpgain_fops); ret = cdev_add(&fsfpgaindev.cdev, fsfpgaindev.devid, FSFPGAIN_CNT); if (0 > ret) { goto fail_cdev; } /* 3、创建类 */ fsfpgaindev.class = class_create(THIS_MODULE, FSFPGAIN_NAME); if (IS_ERR(fsfpgaindev.class)) { ret = PTR_ERR(fsfpgaindev.device); goto fail_class; } /* 4、创建设备 */ fsfpgaindev.device = device_create(fsfpgaindev.class, NULL, fsfpgaindev.devid, NULL, FSFPGAIN_NAME); if (IS_ERR(fsfpgaindev.device)) { ret = PTR_ERR(fsfpgaindev.device); goto fail_device; } printk("*device:0x%x,device:0x%x\r\n", fsfpgaindev.device, &fsfpgaindev.device); // get nd // fsfpgaindev.nd = of_get_parent(spi->dev.of_node); fsfpgaindev.nd = spi->dev.of_node; if (NULL == fsfpgaindev.nd) { printk("fsfpgaindev.nd get error\r\n"); goto fail_gpio; } else { printk("fsfpgaindev.nd name:%s", fsfpgaindev.nd->full_name); } fsfpgaindev.cs_gpio = of_get_named_gpio(fsfpgaindev.nd, "cs-gpio", 0); fsfpgaindev.irq_gpio = of_get_named_gpio(fsfpgaindev.nd, "irq-gpio", 0); if (fsfpgaindev.cs_gpio < 0) { printk("fsfpgaindev.cs_gpio get error\r\n"); goto fail_gpio; /* code */ } if (fsfpgaindev.irq_gpio < 0) { printk("fsfpgaindev.irq_gpio get error\r\n"); goto fail_gpio; /* code */ } // 注册gpio gpio_request(fsfpgaindev.cs_gpio, "cs_gpio"); gpio_request(fsfpgaindev.irq_gpio, "irq_gpio"); printk("fsfpgaindev request cs&irq gpio ok\r\n"); // set gpio ret = gpio_direction_output(fsfpgaindev.cs_gpio, 1); ret = gpio_direction_input(fsfpgaindev.irq_gpio); // // get irq num // fsfpgaindev.irq_num = gpio_to_irq(fsfpgaindev.irq_gpio); // // 注册中断 线程化 // // ret = request_irq(fsfpgaindev.irq_num, irq_gpio_spi_handler, // // IRQF_TRIGGER_FALLING, "irq_gpio", &fsfpgaindev); // ret = request_threaded_irq(fsfpgaindev.irq_num, irq_gpio_spi_handler, // irq_gpio_spi_thread_func, IRQF_TRIGGER_RISING, // "irq_gpio", &fsfpgaindev); // if (0 > ret) { // printk("request_irq error\r\n"); // goto fail_irq; // } // printk("fsfpgaindev request_threaded_irq ok\r\n"); // init spi spi->mode = SPI_MODE_1; ret = spi_setup(spi); printk("spi_setup ret:%d\r\n", ret); // set privete fsfpgaindev.private_data = spi; fsfpgaindev.b_workflag = 0; // 初始化工作状态为不工作 fsfpgaindev.send_data_len = 0; // 初始化spi收发数据长度为0 fsfpgaindev.recv_buf_no = 0; fsfpgaindev.read_buf_no = 0; fsfpgaindev.copy_recv_buf_no = 0; printk("fsfpgain probe ok\r\n"); printk("fsfpgain Debug:005\r\n"); printk("rxvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.rxbuf.v_adr, fsfpgaindev.rxbuf.p_adr); printk("rxvadr:0x%lx padr:0x%x\r\n", (long)&fsfpgaindev.rxbuf.v_adr, &fsfpgaindev.rxbuf.p_adr); printk("txvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.txbuf.v_adr, fsfpgaindev.txbuf.p_adr); // 设置DMA掩码 if ((dma_set_coherent_mask(&spi->dev, DMA_BIT_MASK(32))) != 0) { dev_err(&spi->dev, "Failed to set 32-bit DMA mask\n"); return -ENODEV; } fsfpgaindev.rxbuf.v_adr = dma_alloc_coherent(&spi->dev, 64, &fsfpgaindev.rxbuf.p_adr, GFP_KERNEL); fsfpgaindev.txbuf.v_adr = dma_alloc_coherent(&spi->dev, 32, &fsfpgaindev.txbuf.p_adr, GFP_KERNEL); if ((0x00000000 != fsfpgaindev.rxbuf.v_adr) & (0x00000000 != fsfpgaindev.txbuf.v_adr)) { printk("dma_alloc_coherent ok\r\n"); printk("rxvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.rxbuf.v_adr, fsfpgaindev.rxbuf.p_adr); printk("txvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.txbuf.v_adr, fsfpgaindev.txbuf.p_adr); } else { printk("dma_alloc_coherent return NULL\r\n"); return -1; } // 申请大内存 return ret; fail_irq: gpio_free(fsfpgaindev.cs_gpio); gpio_free(fsfpgaindev.irq_gpio); fail_gpio: fail_device: device_destroy(fsfpgaindev.class, fsfpgaindev.devid); fail_class: class_destroy(fsfpgaindev.class); fail_cdev: cdev_del(&fsfpgaindev.cdev); fail_devid: unregister_chrdev_region(fsfpgaindev.devid, FSFPGAIN_CNT); printk("fsfpgain probe error\r\n"); return ret; } static int fsfpgain_remove(struct spi_device *spi) { int ret = 0; // free irq free_irq(fsfpgaindev.irq_num, &fsfpgaindev); // gpio reset gpio_direction_output(fsfpgaindev.cs_gpio, 0); gpio_direction_output(fsfpgaindev.irq_gpio, 0); // gpio free gpio_free(fsfpgaindev.cs_gpio); gpio_free(fsfpgaindev.irq_gpio); cdev_del(&fsfpgaindev.cdev); unregister_chrdev_region(fsfpgaindev.devid, FSFPGAIN_CNT); device_destroy(fsfpgaindev.class, fsfpgaindev.devid); class_destroy(fsfpgaindev.class); printk("fsfpgain_remove\r\n"); return ret; } // 传统匹配 struct spi_device_id fsfpgain_id[] = {{"fsfpgain", 0}, {}}; // 设备树匹配 static const struct of_device_id fsfpgain_of_match[] = { { .compatible = "fsfpgain", }, {}}; struct spi_driver fsfpgain = { .probe = fsfpgain_probe, .remove = fsfpgain_remove, .id_table = fsfpgain_id, .driver = { .name = "fsfpgain", .owner = THIS_MODULE, .of_match_table = fsfpgain_of_match, }, }; // 入口函数 static int __init fsfpgain_init(void) { int ret = 0; ret = spi_register_driver(&fsfpgain); printk("fsfpgain_init spi_register_driver return:%d\r\n", ret); return ret; } // 出口函数 static void __exit fsfpgain_exit(void) { // 释放大内存 printk("rxvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.rxbuf.v_adr, fsfpgaindev.rxbuf.p_adr); printk("txvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.txbuf.v_adr, fsfpgaindev.txbuf.p_adr); dma_free_coherent(NULL, DMAC_MAX_TRF_SIZE * DMA_RECV_MAX_NUM, fsfpgaindev.rxbuf.v_adr, fsfpgaindev.rxbuf.p_adr); dma_free_coherent(NULL, DMAC_MAX_TRF_SIZE * DMA_RECV_MAX_NUM, fsfpgaindev.txbuf.v_adr, fsfpgaindev.txbuf.p_adr); printk("rxvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.rxbuf.v_adr, fsfpgaindev.rxbuf.p_adr); printk("txvadr:0x%lx padr:0x%x\r\n", (long)fsfpgaindev.txbuf.v_adr, fsfpgaindev.txbuf.p_adr); spi_unregister_driver(&fsfpgain); printk("fsfpgain_exit\r\n"); } module_init(fsfpgain_init); module_exit(fsfpgain_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("fsml"); MODULE_DESCRIPTION("fsfpgain t113 module"); MODULE_VERSION("v2.0.0.0");
问题:
- 没有设置设备,丢了一个NULL进去,这个操作在Linux 5.4 内核中是不允许的
- 没有设置 DMA MASK,4.14之前内核可以,之后的不行
- memset把之前设置的参数全部清空了,不知道有什么作用
-
回复: 【T113 S3】【spi驱动】【DMA 连续内存分配】【dma_alloc_coherent】【失败】
参考 G2D 驱动做下修改
lichee/linux-5.4/drivers/char/sunxi_g2d/g2d_rcq/g2d.c
void *g2d_malloc(__u32 bytes_num, __u32 *phy_addr) { void *address = NULL; #if defined(CONFIG_ION) u32 actual_bytes; if (bytes_num != 0) { actual_bytes = G2D_BYTE_ALIGN(bytes_num); address = dma_alloc_coherent(para.dev, actual_bytes, (dma_addr_t *) phy_addr, GFP_KERNEL); if (address) { return address; } G2D_ERR_MSG("dma_alloc_coherent fail, size=0x%x\n", bytes_num); return NULL; } G2D_ERR_MSG("size is zero\n"); #else unsigned int map_size = 0; struct page *page; if (bytes_num != 0) { map_size = PAGE_ALIGN(bytes_num); page = alloc_pages(GFP_KERNEL, get_order(map_size)); if (page != NULL) { address = page_address(page); if (address == NULL) { free_pages((unsigned long)(page), get_order(map_size)); G2D_ERR_MSG("page_address fail!\n"); return NULL; } *phy_addr = virt_to_phys(address); return address; } G2D_ERR_MSG("alloc_pages fail!\n"); return NULL; } G2D_ERR_MSG("size is zero\n"); #endif return NULL; }
目前看到 dma_alloc_coherent(NULL, xxx...) 的第一个参数是NULL,正常来说应该分配设备而不是NULL。
-
回复: 关于打印启动日志到/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
-
回复: T113 DMA 测试在开启mmu后,测试失败
如何开启的MMU?
我看了下,他只是开启了MMU但是没有配置,没有设置页大小,页表位置,DCACHE,没有设置none cacheable空间
uint32_t value = arm32_read_p15_c1(); arm32_write_p15_c1(value | (1 << 0));
-
回复: DragonFace V4.1.0哪里有下载,你们搞的也太封闭了吧。。。
使用APST量产工具下载,APST下载地址https://open.allwinnertech.com/
-
回复: ep无效,创建hub_tt失败
;-------------------------------- ;[usbc0]: 控制器0的配置。 ;usb_used: USB使能标志。置1,表示系统中USB模块可用,置0,则表示系统USB禁用。 ;usb_port_type: USB端口的使用情况。 0: device only;1: host only;2: OTG ;usb_detect_type: USB端口的检查方式。0: 不做检测;1: vbus/id检查;2: id/dpdm检查 ;usb_detect_mode: USB端口的检查方式。0: 线程轮询;1: id中断触发 ;usb_id_gpio: USB ID pin脚配置。具体请参考gpio配置说明。 ;usb_det_vbus_gpio: USB DET_VBUS pin脚配置。具体请参考gpio配置说明。 ;usb_drv_vbus_gpio: USB DRY_VBUS pin脚配置。具体请参考gpio配置说明。 ;usb_drv_vbus_type: vbus设置方式。0: 无; 1: gpio; 2: axp。 ;usb_det_vbus_gpio: "axp_ctrl",表示axp 提供。 ;usbh_driver_level: usb驱动能力等级 ;usbh_irq_flag: usb中断标志 ;-------------------------------- ;-------------------------------- ;--- USB0控制标志 ;-------------------------------- [usbc0] usb_used = 1 usb_port_type = 2 usb_detect_type = 0 usb_detect_mode = 0 usb_id_gpio = port:PB24<0><0><default><default> usb_det_vbus_gpio = port:PA24<0><0><default><default> usb_drv_vbus_gpio = port:PA29<1><0><default><default> usb_drv_vbus_type = 1 usbh_driver_level = 5 usbh_irq_flag = 0
-
回复: 编译出来的应用文件怎么自动拷贝到/usr/bin目录
将文件打包进入 Tina Linux
Tina Linux 提供 busybox-init-base-files 作为 rootfs 的接口提供用户将文件打包进入固件的功能。busybox-init-base-files 内的文件在打包编译系统的时候会覆盖进入 rootfs 内。文件夹的路径 openwrt/target/v853/v853-vision/busybox-init-base-files
01
配置开机自启
开机自启可以说是嵌入式 Linux 投入应用中最主要的一环。这里以自启动 lv_example 介绍一下 Tina Linux 如何配置开机自启功能开机自启动主要的配置位于 openwrt/target/v853/v853-vision/busybox-init-base-files/etc/init.d 文件夹内。系统启动后会按顺序执行这里的脚本,可以通过编写这里的脚本实现开机自启功能。
02
编写一个 S99lvdemo 的启动脚本,S99 代表他会等待之前的 Sxx 脚本执行完毕他才会执行,这里的排序是字符的顺序。
#!/bin/sh
Start lv_example ....
start() {
printf "Start lv_example .... "
lv_examples 1
}stop() {
printf "Stopping lv_example .... "
}case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esacexit $?
编译、打包烧录,可以看到开机自启了 lvgl 的操作界面。 -
回复: 全志提供的交叉编译环境头文件的问题
@arnis 请使用SDK中提供的工具链,路径
prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin/arm-openwrt-linux-gnueabi-
-
回复: 编译全志V851s的SDK遇到如下问题,有没有同样的
@mysteryli 在 编译全志V851s的SDK遇到如下问题,有没有同样的 中说:
Can't locate FindBin.pm in @INC (you may need to install the FindBin module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at ./scripts/package-metadata.pl line 2.
你遇到的错误信息表明你的Perl环境中缺少或未安装FindBin模块。FindBin模块用于定位当前执行的脚本所在的目录。
要解决此问题,你可以使用以下命令安装FindBin模块:
sudo cpan FindBin
或者,如果你已经安装了cpanm工具,你可以使用以下命令:
sudo cpanm FindBin
-
回复: 全志提供的交叉编译环境头文件的问题
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开发环境,找不到头文件因为没有指定Kernel的头文件目录。或者没有在目标板Linux系统上做开发,没有正确配置交叉编译工具链,没有正确配置目标Kernel的引用。
对于驱动开发可以参考:
https://v853.docs.aw-ol.com/soft/dev_gpio/T113没有IDE开发环境,Linux也不能使用Keil,IAR开发,需要学习Linux的新的开发方法
-
回复: 启动内核卡在Waiting for root device /dev/mmcblk0p2...
sunxi-mmc: probe of 4020000.mmc failed with error -16
主线mmc驱动初始化失败,检查一下mmc相关的dts配置
-
回复: 求教使用百问网v851s的sdk打包问题!
看一下
device/config/chips/v851s/configs/xxx/sys_config.fex
是不是3,如果是3改为-1试试看,3是nand -
回复: D1S 接小屏 频率设置不成功
【FAQ】全志V853芯片 Tina SDK LCD小分辨率DCLK设置问题
https://bbs.aw-ol.com/topic/2367/share/1 -
回复: V851SE TinyVision地表最帅AI开发板来了! @yuzukihd
配置 CONFIG_SUNXI_MALLOC_LEN=0x1400000
修改文件
lichee/brandy-2.0/u-boot-2018/include/configs/sun8iw21p1.h
把
define SUNXI_SYS_MALLOC_LEN (32 << 20)
改为
#ifdef CONFIG_SUNXI_MALLOC_LEN #define SUNXI_SYS_MALLOC_LEN CONFIG_SUNXI_MALLOC_LEN #else #define SUNXI_SYS_MALLOC_LEN (32 << 20) #endif
-
回复: D1s DMA驱动Ledc 问题
#include <stdlib.h> #include <interrupt.h> #include <hal_atomic.h> #include <hal_gpio.h> #include <hal_dma.h> #include <hal_cache.h> #include <sunxi_hal_ledc.h> #ifdef CONFIG_COMPONENTS_PM #include <pm_devops.h> #endif /* define this macro when debugging is required */ /* #define LEDC_DEBUG */ #ifdef LEDC_DEBUG #define ledc_info(fmt, args...) printf("%s()%d - "fmt, __func__, __LINE__, ##args) #else #define ledc_info(fmt, args...) #endif #define led_err(fmt, args...) printf("%s()%d - "fmt, __func__, __LINE__, ##args) #define LEDC_PIN_SLEEP 0 struct ledc_config ledc_config = { .led_count = 3, .reset_ns = 84, .t1h_ns = 800, .t1l_ns = 450, .t0h_ns = 400, .t0l_ns = 850, .wait_time0_ns = 84, .wait_time1_ns = 84, .wait_data_time_ns = 600000, .output_mode = "GRB", }; static unsigned long base_addr = LEDC_BASE; struct sunxi_dma_chan *dma_chan; struct sunxi_led *led; static hal_irqreturn_t sunxi_ledc_irq_handler(void *dummy) { ledc_info("=======enter irq_handler=====\n"); struct sunxi_led *led = (struct sunxi_led *)dummy; unsigned int irq_status; irq_status = hal_ledc_get_irq_status(); hal_ledc_clear_all_irq(); if (irq_status & LEDC_TRANS_FINISH_INT) led->result = RESULT_COMPLETE; if (irq_status & LEDC_WAITDATA_TIMEOUT_INT) led->result = RESULT_ERR; if (irq_status & LEDC_FIFO_OVERFLOW_INT) led->result = RESULT_ERR; led->config.length = 0; hal_ledc_reset(); return HAL_IRQ_OK; } int sunxi_led_get_config(struct ledc_config *config) { *config = ledc_config; return 0; } static int ledc_clk_init(void) { hal_clk_type_t clk_type = HAL_SUNXI_CCU; hal_clk_id_t mod_clk_id = CLK_LEDC; hal_clk_id_t bus_clk_id = CLK_BUS_LEDC; hal_reset_type_t reset_type = HAL_SUNXI_RESET; #ifdef CONFIG_ARCH_SUN20IW2 hal_reset_id_t reset_id = RST_LEDC; #else hal_reset_id_t reset_id = RST_BUS_LEDC; #endif #ifdef CONFIG_ARCH_SUN8IW18P1 hal_clock_enable(CLK_BUS_LEDC); #else led->reset = hal_reset_control_get(reset_type, reset_id); if (hal_reset_control_deassert(led->reset)) { ledc_info("ledc reset deassert failed!"); return -1; } hal_reset_control_put(led->reset); led->mod_clk = hal_clock_get(clk_type, mod_clk_id); if (hal_clock_enable(led->mod_clk)) { ledc_info("ledc clk enable mclk failed!"); return -1; } led->bus_clk = hal_clock_get(clk_type, bus_clk_id); if (hal_clock_enable(led->bus_clk)) { ledc_info("ledc clk enable mclk failed!"); return -1; } #endif return 0; } static void ledc_clk_exit(void) { #ifdef CONFIG_ARCH_SUN8IW18P1 hal_clock_disable(CLK_BUS_LEDC); #else hal_clock_disable(led->bus_clk); hal_clock_disable(led->bus_clk); hal_reset_control_assert(led->reset); #endif } static int ledc_pinctrl_init(void) { if (hal_gpio_pinmux_set_function(LEDC_PIN, LEDC_PINMUXSEL)) { ledc_info("ledc pin set default function failed!"); return -1; } return 0; } static void ledc_pinctrl_exit(void) { hal_gpio_pinmux_set_function(LEDC_PIN, LEDC_PIN_SLEEP); } static void ledc_dump_reg(void) { ledc_info("LEDC_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_CTRL_REG)); ledc_info("LED_T01_TIMING_CTRL_REG = %0x\n", hal_readl(base_addr + LED_T01_TIMING_CTRL_REG)); ledc_info("LEDC_DATA_FINISH_CNT_REG = %0x\n", hal_readl(base_addr + LEDC_DATA_FINISH_CNT_REG)); ledc_info("LED_RST_TIMING_CTRL_REG = %0x\n", hal_readl(base_addr + LED_RST_TIMING_CTRL_REG)); ledc_info("LEDC_WAIT_TIME0_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_WAIT_TIME0_CTRL_REG)); ledc_info("LEDC_DATA_REG = %0x\n", hal_readl(base_addr + LEDC_DATA_REG)); ledc_info("LEDC_DMA_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_DMA_CTRL_REG)); ledc_info("LEDC_INTC_REG = %0x\n", hal_readl(base_addr + LEDC_INTC_REG)); ledc_info("LEDC_INTS_REG = %0x\n", hal_readl(base_addr + LEDC_INTS_REG)); ledc_info("LEDC_WAIT_TIME1_CTRL_REG = %0x\n", hal_readl(base_addr + LEDC_WAIT_TIME1_CTRL_REG)); ledc_info("LEDC_FIFO_DATA0_REG = %0x\n", hal_readl(base_addr + LEDC_FIFO_DATA0_REG)); } static void ledc_set_reset_ns(unsigned int reset_ns) { unsigned int n, reg_val; unsigned int mask = 0x1FFF; unsigned int min = LEDC_RESET_TIME_MIN_NS; unsigned int max = LEDC_RESET_TIME_MAX_NS; if (reset_ns < min || reset_ns > max) { ledc_info("invalid parameter, reset_ns should be %u-%u!\n", min, max); return; } n = (reset_ns - 42) / 42; reg_val = hal_readl(base_addr + LED_RST_TIMING_CTRL_REG); reg_val &= ~(mask << 16); reg_val |= (n << 16); hal_writel(reg_val, base_addr + LED_RST_TIMING_CTRL_REG); } static void ledc_set_t1h_ns(unsigned int t1h_ns) { unsigned int n, reg_val; unsigned int mask = 0x3F; unsigned int shift = 21; unsigned int min = LEDC_T1H_MIN_NS; unsigned int max = LEDC_T1H_MAX_NS; if (t1h_ns < min || t1h_ns > max) { ledc_info("invalid parameter, t1h_ns should be %u-%u!\n", min, max); return; } n = (t1h_ns - 42) / 42; reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG); reg_val &= ~(mask << shift); reg_val |= n << shift; hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG); } static void ledc_set_t1l_ns(unsigned int t1l_ns) { unsigned int n, reg_val; unsigned int mask = 0x1F; unsigned int shift = 16; unsigned int min = LEDC_T1L_MIN_NS; unsigned int max = LEDC_T1L_MAX_NS; if (t1l_ns < min || t1l_ns > max) { ledc_info("invalid parameter, t1l_ns should be %u-%u!\n", min, max); return; } n = (t1l_ns - 42) / 42; reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG); reg_val &= ~(mask << shift); reg_val |= n << shift; hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG); } static void ledc_set_t0h_ns(unsigned int t0h_ns) { unsigned int n, reg_val; unsigned int mask = 0x1F; unsigned int shift = 6; unsigned int min = LEDC_T0H_MIN_NS; unsigned int max = LEDC_T0H_MAX_NS; if (t0h_ns < min || t0h_ns > max) { ledc_info("invalid parameter, t0h_ns should be %u-%u!\n", min, max); return; } n = (t0h_ns - 42) / 42; reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG); reg_val &= ~(mask << shift); reg_val |= n << shift; hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG); } static void ledc_set_t0l_ns(unsigned int t0l_ns) { unsigned int n, reg_val; unsigned int min = LEDC_T0L_MIN_NS; unsigned int max = LEDC_T0L_MAX_NS; if (t0l_ns < min || t0l_ns > max) { ledc_info("invalid parameter, t0l_ns should be %u-%u!\n", min, max); return; } n = (t0l_ns - 42) / 42; reg_val = hal_readl(base_addr + LED_T01_TIMING_CTRL_REG); reg_val &= ~0x3F; reg_val |= n; hal_writel(reg_val, base_addr + LED_T01_TIMING_CTRL_REG); } static void ledc_set_wait_time0_ns(unsigned int wait_time0_ns) { unsigned int n, reg_val; unsigned int min = LEDC_WAIT_TIME0_MIN_NS; unsigned int max = LEDC_WAIT_TIME0_MAX_NS; if (wait_time0_ns < min || wait_time0_ns > max) { ledc_info("invalid parameter, wait_time0_ns should be %u-%u!\n", min, max); return; } n = (wait_time0_ns - 42) / 42; reg_val = (1 << 8) | n; hal_writel(reg_val, base_addr + LEDC_WAIT_TIME0_CTRL_REG); } static void ledc_set_wait_time1_ns(unsigned long long wait_time1_ns) { //unsigned long tmp; unsigned long long max = LEDC_WAIT_TIME1_MAX_NS; unsigned int min = LEDC_WAIT_TIME1_MIN_NS; unsigned int n, reg_val; if (wait_time1_ns < min || wait_time1_ns > max) { ledc_info("invalid parameter, wait_time1_ns should be %u-%llu!\n", min, max); return; } n = wait_time1_ns / 42; //tmp = wait_time1_ns; //n = div_u64(tmp, 42); n -= 1; reg_val = (1 << 31) | n; hal_writel(reg_val, base_addr + LEDC_WAIT_TIME1_CTRL_REG); } static void ledc_set_wait_data_time_ns(unsigned int wait_data_time_ns) { unsigned int mask = 0x1FFF; unsigned int shift = 16; unsigned int reg_val = 0; unsigned int n, min, max; min = LEDC_WAIT_DATA_TIME_MIN_NS; max = LEDC_WAIT_DATA_TIME_MAX_NS_IC; if (wait_data_time_ns < min || wait_data_time_ns > max) { ledc_info("invalid parameter, wait_data_time_ns should be %u-%u!\n", min, max); return; } n = (wait_data_time_ns - 42) / 42; reg_val &= ~(mask << shift); reg_val |= (n << shift); hal_writel(reg_val, base_addr + LEDC_DATA_FINISH_CNT_REG); } static void ledc_set_length(unsigned int length) { unsigned int reg_val; if (length == 0) return; reg_val = hal_readl(base_addr + LEDC_CTRL_REG); reg_val &= ~(0x1FFF << 16); reg_val |= length << 16; hal_writel(reg_val, base_addr + LEDC_CTRL_REG); reg_val = hal_readl(base_addr + LED_RST_TIMING_CTRL_REG); reg_val &= ~0x3FF; reg_val |= length - 1; hal_writel(reg_val, base_addr + LED_RST_TIMING_CTRL_REG); } static void ledc_set_output_mode(const char *str) { unsigned int val = 0; unsigned int mask = 0x7; unsigned int shift = 6; unsigned int reg_val ; if (str != NULL) { if (!strncmp(str, "GRB", 3)) val = LEDC_OUTPUT_GRB; else if (!strncmp(str, "GBR", 3)) val = LEDC_OUTPUT_GBR; else if (!strncmp(str, "RGB", 3)) val = LEDC_OUTPUT_RGB; else if (!strncmp(str, "RBG", 3)) val = LEDC_OUTPUT_RBG; else if (!strncmp(str, "BGR", 3)) val = LEDC_OUTPUT_BGR; else if (!strncmp(str, "BRG", 3)) val = LEDC_OUTPUT_BRG; else return; } else { } reg_val = hal_readl(base_addr + LEDC_CTRL_REG); reg_val &= ~(mask << shift); reg_val |= val; hal_writel(reg_val, base_addr + LEDC_CTRL_REG); } static void ledc_disable_irq(unsigned int mask) { unsigned int reg_val = 0; reg_val = hal_readl(base_addr + LEDC_INTC_REG); reg_val &= ~mask; hal_writel(reg_val, base_addr + LEDC_INTC_REG); } static void ledc_enable_irq(unsigned int mask) { unsigned int reg_val = 0; reg_val = hal_readl(base_addr + LEDC_INTC_REG); reg_val |= mask; hal_writel(reg_val, base_addr + LEDC_INTC_REG); } static void ledc_set_dma_mode(void) { unsigned int reg_val = 0; reg_val |= 1 << 5; hal_writel(reg_val, base_addr + LEDC_DMA_CTRL_REG); } static void ledc_set_cpu_mode(void) { unsigned int reg_val = 0; reg_val &= ~(1 << 5); hal_writel(reg_val, base_addr + LEDC_DMA_CTRL_REG); } static void ledc_clear_all_irq(void) { unsigned int reg_val; reg_val = hal_readl(base_addr + LEDC_INTS_REG); reg_val |= 0x1F; hal_writel(reg_val, base_addr + LEDC_INTS_REG); } static unsigned int ledc_get_irq_status(void) { return hal_readl(base_addr + LEDC_INTS_REG); } static void ledc_soft_reset(void) { unsigned int reg_val; reg_val = hal_readl(base_addr + LEDC_CTRL_REG); reg_val |= 1 << 1; hal_writel(reg_val, base_addr + LEDC_CTRL_REG); } static void ledc_reset_en(void) { unsigned int reg_val; reg_val = hal_readl(base_addr + LEDC_CTRL_REG); reg_val |= 1 << 10; hal_writel(reg_val, base_addr + LEDC_CTRL_REG); } static void ledc_set_data(unsigned int data) { hal_writel(data, base_addr + LEDC_DATA_REG); } static void ledc_enable(void) { unsigned int reg_val; reg_val = hal_readl(base_addr + LEDC_CTRL_REG); reg_val |= 1; hal_writel(reg_val, base_addr + LEDC_CTRL_REG); } static void hal_ledc_set_time(struct ledc_config *ledc) { ledc_set_reset_ns(ledc->reset_ns); ledc_set_t1h_ns(ledc->t1h_ns); ledc_set_t1l_ns(ledc->t1l_ns); ledc_set_t0h_ns(ledc->t0h_ns); ledc_set_t0l_ns(ledc->t0l_ns); ledc_set_wait_time0_ns(ledc->wait_time0_ns); ledc_set_wait_time1_ns(ledc->wait_time1_ns); ledc_set_wait_data_time_ns(ledc->wait_data_time_ns); } void hal_ledc_dma_callback(void *para) { printf("dma callback\n"); } void hal_ledc_trans_data(struct ledc_config *ledc) { int i; unsigned long int size; unsigned int mask = 0; struct dma_slave_config slave_config; mask = LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN; if (ledc->length <= SUNXI_LEDC_FIFO_DEPTH) { ledc_info("trans data by CPU mode\n"); mask |= LEDC_FIFO_CPUREQ_INT_EN; ledc_reset_en(); hal_ledc_set_time(ledc); ledc_set_output_mode(ledc->output_mode); ledc_set_cpu_mode(); ledc_set_length(ledc->length); ledc_enable_irq(mask); for(i = 0; i < ledc->length; i++) ledc_set_data(ledc->data[i]); ledc_enable(); } else { ledc_info("trans data by DMA mode\n"); mask &= ~LEDC_FIFO_CPUREQ_INT_EN; ledc_reset_en(); size = ledc->length * 4; hal_dcache_clean((unsigned long)ledc->data, sizeof(ledc->data)); slave_config.direction = DMA_MEM_TO_DEV; slave_config.src_addr = (unsigned long)(ledc->data); slave_config.dst_addr = (uint32_t)(base_addr + LEDC_DATA_REG); slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; slave_config.src_maxburst = DMA_SLAVE_BURST_16; slave_config.dst_maxburst = DMA_SLAVE_BURST_16; slave_config.slave_id = sunxi_slave_id(DRQDST_LEDC, DRQSRC_SDRAM); hal_dma_slave_config(dma_chan, &slave_config); hal_dma_prep_device(dma_chan, slave_config.dst_addr, slave_config.src_addr, size, DMA_MEM_TO_DEV); //dma_chan->callback = ledc_dma_callback; hal_dma_start(dma_chan); hal_ledc_set_time(ledc); ledc_set_output_mode(ledc->output_mode); ledc_set_length(ledc->length); ledc_set_dma_mode(); ledc_enable_irq(mask); ledc_enable(); } } void hal_ledc_clear_all_irq(void) { ledc_clear_all_irq(); } unsigned int hal_ledc_get_irq_status(void) { return ledc_get_irq_status(); } void hal_ledc_reset(void) { ledc_disable_irq(LEDC_TRANS_FINISH_INT_EN | LEDC_WAITDATA_TIMEOUT_INT_EN | LEDC_FIFO_OVERFLOW_INT_EN | LEDC_GLOBAL_INT_EN | LEDC_GLOBAL_INT_EN); if (dma_chan) { hal_dma_stop(dma_chan); } ledc_soft_reset(); } #ifdef CONFIG_COMPONENTS_PM static inline void sunxi_ledc_save_regs(struct sunxi_led *led) { int i; for (i = 0; i < ARRAY_SIZE(sunxi_ledc_regs_offset); i++) led->regs_backup[i] = readl(base_addr + sunxi_ledc_regs_offset[i]); } static inline void sunxi_ledc_restore_regs(struct sunxi_led *led) { int i; for (i = 0; i < ARRAY_SIZE(sunxi_ledc_regs_offset); i++) writel(led->regs_backup[i], base_addr + sunxi_ledc_regs_offset[i]); } static int hal_ledc_resume(struct pm_device *dev, suspend_mode_t mode) { int ret = 0; if (ledc_clk_init()) { led_err("ledc clk init failed \n"); ret = -1; goto err0; } if (ledc_pinctrl_init()) { led_err("ledc pinctrl init failed \n"); ret = -1; goto err1; } sunxi_ledc_restore_regs(led); hal_enable_irq(SUNXI_IRQ_LEDC); ledc_info("hal ledc resume"); return 0; err1: ledc_clk_exit(); err0: return ret; } static int hal_ledc_suspend(struct pm_device *dev, suspend_mode_t mode) { hal_disable_irq(SUNXI_IRQ_LEDC); sunxi_ledc_save_regs(led); ledc_pinctrl_exit(); ledc_clk_exit(); ledc_info("hal ledc suspend"); return 0; } struct pm_devops pm_ledc_ops = { .suspend = hal_ledc_suspend, .resume = hal_ledc_resume, }; struct pm_device pm_ledc = { .name = "sunxi_ledc", .ops = &pm_ledc_ops, }; #endif int hal_ledc_init(void) { ledc_info("hal_led_init\n"); led = malloc(sizeof(struct sunxi_led)); if (NULL == led) { led_err("sunxi led malloc err\n"); return -1; } sunxi_led_get_config(&led->config); led->config.data = malloc(sizeof(unsigned int) * led->config.led_count); if (NULL == led->config.data) { led_err("sunxi led config data malloc err\n"); goto err1; } if (ledc_clk_init()) { led_err("ledc clk init failed \n"); } if (ledc_pinctrl_init()) { led_err("ledc pinctrl init failed \n"); } hal_dma_chan_request(&dma_chan); if (hal_request_irq(SUNXI_IRQ_LEDC, sunxi_ledc_irq_handler, "ledc", led) < 0) { led_err("ledc request irq failed \n"); goto errirq; } hal_enable_irq(SUNXI_IRQ_LEDC); #ifdef CONFIG_COMPONENTS_PM pm_devops_register(&pm_ledc); #endif ledc_info("hal_led_init success\n"); return 0; errirq: free(led->config.data); err1: free(led); return -1; } void hal_ledc_deinit(void) { #ifdef CONFIG_COMPONENTS_PM pm_devops_unregister(&pm_ledc); #endif hal_disable_irq(SUNXI_IRQ_LEDC); hal_free_irq(SUNXI_IRQ_LEDC); hal_dma_chan_free(dma_chan); ledc_pinctrl_exit(); ledc_clk_exit(); free(led->config.data); free(led); } int sunxi_set_all_led(unsigned int brightness) { int i; led->config.length = led->config.led_count; for(i = 0;i < led->config.led_count;i++) led->config.data[i] = brightness; hal_ledc_trans_data(&led->config); return 0; } int sunxi_set_led_brightness(int led_num, unsigned int brightness) { u32 reg_val; if (NULL == led) { led_err("err : ledc is not init\n"); return -1; } if (led_num > led->config.led_count) { led_err("has not the %d led\n", led_num); return -1; } led->config.length = 1; led->config.data[led_num-1] = brightness; hal_ledc_trans_data(&led->config); reg_val = hal_ledc_get_irq_status(); ledc_info("ledc interrupt status reg is %x", reg_val); return 0; }
-
回复: V853 可以拉取多个摄像头的子码流做分析吗,单核是不是有压力
v853可以三路输入,可以外接三个摄像头。
ffmpeg可以硬件编解码,但是需要自己编写对接硬件codec的部分,ffmpeg官方没有支持这部分