一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

linux input輸入子系統(tǒng)分析《二》:s3c2440的ADC簡(jiǎn)單驅(qū)動(dòng)實(shí)例分析

 云將東游 2016-03-15


轉(zhuǎn)自:

http://blog.csdn.net/ielife/article/details/7798999

主要講述本人在學(xué)習(xí)Linux內(nèi)核input子系統(tǒng)的全部過程,如有分析不當(dāng),多謝指正。以下交流方式,文章歡迎轉(zhuǎn)載,保留聯(lián)系信息,以便交流。

郵箱:eabi010@gmail.com

主頁:www.(愛嵌論壇——嵌入式技術(shù)學(xué)習(xí)交流)

博客:blog.csdn.net/ielife


1      mini2440的ADC驅(qū)動(dòng)實(shí)例

這節(jié)與輸入子系統(tǒng)無關(guān),出現(xiàn)在這里是因?yàn)楹竺娴恼鹿?jié)會(huì)講到觸摸屏輸入子系統(tǒng)驅(qū)動(dòng),由于觸摸屏也使用ADC,因此本節(jié)是為了說明ADC通過驅(qū)動(dòng)代碼是如何控制的。

本節(jié)重點(diǎn):

  • 如何通過原理圖查找ADC硬件使用的資源
  • 如何通過芯片手冊(cè)查找ADC硬件的操作方法
  • ADC設(shè)備驅(qū)動(dòng)程序的初始化流程
  • ADC設(shè)備驅(qū)動(dòng)程序的中斷處理流程

本節(jié)難點(diǎn):

  • ADC的控制寄存器的操作方法
  • ADC驅(qū)動(dòng)程序的控制邏輯

1.1    模數(shù)轉(zhuǎn)換(ADC)簡(jiǎn)介

ADC是把模擬信號(hào)轉(zhuǎn)化為計(jì)算機(jī)能夠處理的數(shù)字信號(hào)的過程。

模擬信號(hào)一般為電壓,或者是電流。有些時(shí)候也可以是非電信號(hào),如溫度、濕度、聲音、位移等,它們通過傳感器轉(zhuǎn)換為電壓信號(hào)傳遞給A/D轉(zhuǎn)換器才可以進(jìn)行A/D轉(zhuǎn)換。

1.2    mini2440上的可調(diào)電阻

由mini2440的用戶手冊(cè)的1.3.8節(jié)A/D輸入測(cè)試可知,S3C2440的AIN0引腳接到了開發(fā)板的可調(diào)電阻W1上,原理圖如下圖3所示:



圖3  mini2440可調(diào)電阻原理圖

 

上圖中,1、2電路的狀態(tài)是能夠確定的,一個(gè)接3.3V電壓,一個(gè)接地,中間接可變電阻W1(10K)。而引腳3接AIN0,它是什么?可以通過mini2440開發(fā)板原理圖來查找:



圖4  mini2440可調(diào)電阻與S3C2440接口電路

 

通過上圖可知,開發(fā)板的AIN0引腳與S3C2440 CPU芯片上的AIN0引腳相連接。因此需要進(jìn)一步查看S3C2440芯片手冊(cè)獲得AIN0引腳的作用。

下圖5是S3C2440芯片手冊(cè)的第16章對(duì)A/D轉(zhuǎn)換器和觸摸屏接口的介紹。S3C2440內(nèi)部共有8個(gè)通道的模擬輸入接口,其轉(zhuǎn)換的模擬信號(hào)為10位的二進(jìn)制數(shù)字編碼。

A[3:0]分別代表AIN0、AIN1、AIN2、AIN3,觸摸屏接口可以控制/選擇觸摸屏X、Y方向的引腳(XP,XM,YP,YM)的變換。



圖5  A/D轉(zhuǎn)換器和觸摸屏的功能結(jié)構(gòu)圖

 

那么ADC如何實(shí)現(xiàn)模擬信號(hào)到數(shù)字信號(hào)的轉(zhuǎn)換呢,由上圖可知,模擬信號(hào)通過8個(gè)通道的任意一個(gè)輸入,然后通過分頻器決定A/D轉(zhuǎn)換器的頻率,最后通過ADC將模擬信號(hào)轉(zhuǎn)換為數(shù)字信號(hào)保存在ADCDAT0中,ADCDAT0中的數(shù)據(jù)可以通過查詢或者中斷的方式來獲得。

S3C2440模數(shù)轉(zhuǎn)換器的控制邏輯可由以下寄存器來進(jìn)行操作:

ADCCON       ADC控制寄存器

ADCTSC        ADC觸摸屏控制寄存器器

ADCDLY ADC啟動(dòng)初始化延遲寄存器

ADCDAT0      ADC轉(zhuǎn)換數(shù)據(jù)寄存器

ADCDAT1      ADC轉(zhuǎn)換數(shù)據(jù)寄存器

ADCUPDN     筆尖抬起或落下中斷狀態(tài)寄存器

由以上內(nèi)容,開發(fā)板可以通過W1可變電阻的阻值變化產(chǎn)生電壓的變化,由AIN0引腳傳遞給ADC控制器轉(zhuǎn)化為數(shù)字信號(hào),我們通過驅(qū)動(dòng)來獲得可調(diào)電阻W1硬件的變化。

1.3    可調(diào)電阻的ADC驅(qū)動(dòng)程序

既然需要寫驅(qū)動(dòng),首先先確定可調(diào)電阻的ADC驅(qū)動(dòng)屬于什么設(shè)備。由于是順序讀取寄存器ADCDAT0的過程,所以把它看成一個(gè)字符設(shè)備,而且對(duì)于這個(gè)設(shè)備來說,更簡(jiǎn)單的實(shí)現(xiàn)方法是通過misc雜項(xiàng)設(shè)備來實(shí)現(xiàn)。

代碼實(shí)現(xiàn)的非常簡(jiǎn)單,通過中斷的方式獲取ADCDAT0的前10位的值就可以了。代碼如下:

  1. /* 
  2.  * mini2440 ADC驅(qū)動(dòng)程序 
  3.  * 
  4.  * Kevin Lee <www.> 
  5.  */  
  6.    
  7. #include<linux/kernel.h> /* 提供prink等內(nèi)核特有屬性 */  
  8. #include<linux/module.h> /* 提供如MODULE_LICENSE()、EXPORT_SYMBOL() */  
  9. #include<linux/init.h> /* 設(shè)置段,如_init、_exit,設(shè)置初始化優(yōu)先級(jí),如__initcall */  
  10. #include<linux/wait.h> /* 等待隊(duì)列wait_queue */  
  11. #include<linux/interrupt.h> /* 中斷方式,如IRQF_SHARED */  
  12. #include<linux/fs.h> /* file_operations操作接口等 */  
  13. #include<linux/clk.h> /* 時(shí)鐘控制接口,如struct clk */  
  14. #include<linux/miscdevice.h> /* 雜項(xiàng)設(shè)備 */  
  15. #include<asm/io.h> /* 提供readl、writel */  
  16. #include<asm/irq.h> /* 提供中斷號(hào),中斷類型等,如IRQ_ADC中斷號(hào) */  
  17. #include<asm/arch/regs-adc.h> /* 提供控制器的寄存器操作,如S3C2410_ADCCON */  
  18. #include<asm/uaccess.h> /* 提供copy_to_user等存儲(chǔ)接口 */  
  19.    
  20. /* 定義設(shè)備名稱,用戶訪問接口/dev/adc */  
  21. #defineDEVICE_NAME "adc"  
  22.    
  23. /* 定義adc時(shí)鐘,通過adc_clock接口獲得adc輸入時(shí)鐘,adc轉(zhuǎn)換器需要 */  
  24. staticstruct clk *adc_clock;  
  25.    
  26. /* 定義虛擬地址訪問硬件寄存器,__iomem只是用于表示指針將指向I/O內(nèi)存 */  
  27. staticvoid __iomem *base_addr;  
  28.    
  29. /* 定義并初始化一個(gè)等待隊(duì)列adc_waitqueue,對(duì)ADC資源進(jìn)行阻塞訪問 */  
  30. staticwait_queue_head_t adc_waitqueue;  
  31.    
  32. /* 定義并初始化信號(hào)量adc_lock,用于控制共享中斷IRQ_ADC資源的使用 */  
  33. DECLARE_MUTEX(adc_lock);  
  34. EXPORT_SYMBOL(adc_lock);  
  35.    
  36. /* 定義等待隊(duì)列的條件,當(dāng)is_read_ok=1時(shí),ADC轉(zhuǎn)換完畢,數(shù)據(jù)可讀 */  
  37. staticvolatile int is_read_ok = 0;  
  38.    
  39. /* 定義ADC轉(zhuǎn)換的數(shù)據(jù)內(nèi)容 */  
  40. staticvolatile int adc_data;  
  41.    
  42. staticint adc_open(struct inode *inode, struct file *file);  
  43. staticssize_t adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos);  
  44. staticint adc_close(struct inode *inode, struct file *filp);  
  45.    
  46. /* 實(shí)現(xiàn)字符設(shè)備操作接口 */  
  47. staticstruct file_operations adc_fops =  
  48. {  
  49.     .owner   = THIS_MODULE,  
  50.     .open    = adc_open,  
  51.     .read    = adc_read,     
  52.     .release = adc_close,  
  53. };  
  54.    
  55. /* 實(shí)現(xiàn)misc雜項(xiàng)設(shè)備操作接口 */  
  56. staticstruct miscdevice adc_miscdev =  
  57. {  
  58.     .minor  = MISC_DYNAMIC_MINOR, /* 動(dòng)態(tài)獲取雜項(xiàng)設(shè)備的次設(shè)備號(hào) */  
  59.     .name   = DEVICE_NAME,        /* 雜項(xiàng)設(shè)備的設(shè)備名稱,這里為adc */  
  60.     .fops   = &adc_fops,          /* 雜項(xiàng)設(shè)備子系統(tǒng)接口,指向adc_fops操作接口 */  
  61. };  
  62.    
  63. /*ADC中斷服務(wù)程序,獲取ADC轉(zhuǎn)換后的數(shù)據(jù) */  
  64. staticirqreturn_t adc_irq(int irq, void *dev_id)  
  65. {  
  66.     /* 僅當(dāng)is_read_ok=0時(shí)才進(jìn)行轉(zhuǎn)換,防止多次中斷 */  
  67.     if(!is_read_ok)  
  68.     {  
  69.         /* 讀取ADCCON[9:0]的值,0x3ff為只獲取[9:0]位,ADCCON為轉(zhuǎn)換后的數(shù)據(jù) */  
  70.         adc_data = readl(base_addr +S3C2410_ADCDAT0) & 0x3ff;  
  71.    
  72.         /* 設(shè)置標(biāo)識(shí)為1,喚醒讀等待進(jìn)程可以拷貝數(shù)據(jù)給用戶空間了 */  
  73.         is_read_ok = 1;  
  74.        wake_up_interruptible(&adc_waitqueue);  
  75.     }  
  76.    
  77.     return IRQ_RETVAL(IRQ_HANDLED);  
  78. }  
  79.    
  80. /*ADC設(shè)備打開,并注冊(cè)IRQ_ADC中斷處理函數(shù) */  
  81. staticint adc_open(struct inode *inode, struct file *file)  
  82. {  
  83.     int ret;  
  84.    
  85.     /* 由于IRQ_ADC為共享中斷,因此中斷類型選擇IRQF_SHARED,最后一個(gè)參數(shù)需要設(shè)置NULL以外的值 */  
  86.     ret = request_irq(IRQ_ADC, adc_irq,IRQF_SHARED, DEVICE_NAME, (void *)1);  
  87.     if (ret)  
  88.     {  
  89.         printk(KERN_ERR "Could notallocate ts IRQ_ADC !\n");  
  90.         return -EBUSY;  
  91.     }  
  92.    
  93.     return 0;  
  94. }  
  95.    
  96. /*設(shè)置ADC控制寄存器,開啟AD轉(zhuǎn)換*/  
  97. staticvoid adc_run(void)  
  98. {  
  99.     volatile unsigned int adccon;  
  100.      
  101.     /* ADCCON的位[14]=1為使能A/D預(yù)分頻器,位[13:6]=32表示設(shè)置的分頻值,ADC的轉(zhuǎn)換頻率需要在2.5MHZ以下 
  102.      * 我們使用的ADC輸入時(shí)鐘為PCLK=50MHZ,50MHZ/32<2.5MHZ,滿足條件 
  103.      * 位[5:3]=000,表示模擬輸入通道選擇AIN0 
  104.      */  
  105.     adccon = (1 << 14) | (32 << 6);  
  106.     writel(adccon, base_addr + S3C2410_ADCCON);  
  107.      
  108.     /* 位[0]=1表示使能ADC轉(zhuǎn)換,當(dāng)轉(zhuǎn)換完畢后此位被ADC控制器自動(dòng)清0 */  
  109.     adccon = readl(base_addr + S3C2410_ADCCON)| (1 << 0);  
  110.     writel(adccon, base_addr + S3C2410_ADCCON);  
  111. }  
  112.    
  113. /*ADC設(shè)備驅(qū)動(dòng)讀函數(shù) */  
  114. staticssize_t adc_read(struct file *filp, char *buff, size_t count, loff_t *offp)  
  115. {  
  116.     int err;  
  117.    
  118.     /* 獲取信號(hào)量,如果被占用,睡眠等待持有者調(diào)用up喚醒 
  119.      * 這樣做的原因是,有可能其他進(jìn)程搶占執(zhí)行或是觸摸屏驅(qū)動(dòng)搶占執(zhí)行 
  120.      */  
  121.     down_interruptible(&adc_lock);  
  122.    
  123.     /* 啟動(dòng)adc轉(zhuǎn)換,調(diào)用中斷處理函數(shù)adc_irq*/  
  124.     adc_run();  
  125.    
  126.     /* 如果is_read_ok為假,則睡眠等待條件為真,由中斷處理函數(shù)喚醒 */  
  127.     wait_event_interruptible(adc_waitqueue,is_read_ok);  
  128.    
  129.     /* 執(zhí)行到此說明中斷處理程序獲得了ADC轉(zhuǎn)換后的值,清除為0等待下一次的讀 */  
  130.     is_read_ok = 0;  
  131.    
  132.     /* 將轉(zhuǎn)換后的數(shù)據(jù)adc_data提交給用戶 */  
  133.     err = copy_to_user(buff, (char*)&adc_data, min(sizeof(adc_data),count));  
  134.    
  135.     /* 釋放信號(hào)量,并喚醒因adc_lock而睡眠的進(jìn)程 */  
  136.     up(&adc_lock);  
  137.    
  138.     return err ? -EFAULT : sizeof(adc_data);  
  139. }  
  140.    
  141. /*ADC設(shè)備關(guān)閉函數(shù) */  
  142. staticint adc_close(struct inode *inode, struct file *filp)  
  143. {  
  144.     /*釋放中斷*/  
  145.     free_irq(IRQ_ADC, (void *)1);     
  146.     return 0;  
  147. }  
  148.    
  149. staticint __init adc_init(void)  
  150. {  
  151.     int ret;  
  152.    
  153.     /* 獲得adc的時(shí)鐘源,通過arch/arm/mach-s3c2410/clock.c獲得提供的時(shí)鐘源為PCLK */  
  154.     adc_clock = clk_get(NULL, "adc");  
  155.     if (!adc_clock)  
  156.     {  
  157.         printk(KERN_ERR "failed to get adcclock source\n");  
  158.         return -ENOENT;  
  159.     }  
  160.    
  161.     /* 在時(shí)鐘控制器中給adc提供輸入時(shí)鐘,ADC轉(zhuǎn)換需要輸入時(shí)鐘 */  
  162.     clk_enable(adc_clock);  
  163.    
  164.     /* 使用ioremap獲得操作ADC控制器的虛擬地址 
  165.      * S3C2410_PA_ADC=ADCCON,是ADC控制器的基地址,寄存器組的長(zhǎng)度=0x1c 
  166.      */  
  167.     base_addr = ioremap(S3C2410_PA_ADC, 0x1c);  
  168.     if (base_addr == NULL)  
  169.     {  
  170.         printk(KERN_ERR "Failed to remapregister block\n");  
  171.         return -ENOMEM;  
  172.         goto fail1;  
  173.     }  
  174.      
  175.     /* 初始化等待隊(duì)列 */  
  176.     init_waitqueue_head(&adc_waitqueue);  
  177.    
  178.     /* 注冊(cè)雜項(xiàng)設(shè)備 */  
  179.     ret = misc_register(&adc_miscdev);  
  180.     if (ret)  
  181.     {  
  182.         printk(KERN_ERR "Failed toregister miscdev\n");  
  183.         goto fail2;  
  184.     }  
  185.    
  186.     printk(DEVICE_NAME "initialized!\n");  
  187.    
  188.     return 0;  
  189.      
  190. fail2:  
  191.     iounmap(base_addr);  
  192. fail1:  
  193.     clk_disable(adc_clock);  
  194.     clk_put(adc_clock);  
  195.    
  196.     return ret;  
  197. }  
  198.    
  199. staticvoid __exit adc_exit(void)  
  200. {  
  201.     /* 釋放虛擬地址 */  
  202.     iounmap(base_addr);  
  203.    
  204.     /* 禁止ADC的時(shí)鐘源 */  
  205.     if (adc_clock)              
  206.     {  
  207.         clk_disable(adc_clock);  
  208.         clk_put(adc_clock);  
  209.         adc_clock = NULL;  
  210.     }  
  211.    
  212.     /*注銷misc設(shè)備*/  
  213.     misc_deregister(&adc_miscdev);  
  214. }  
  215.    
  216. module_init(adc_init);  
  217. module_exit(adc_exit);  
  218.    
  219. MODULE_AUTHOR("KevinLee <www.>");  
  220. MODULE_DESCRIPTION("Mini2440ADC Misc Device Driver");  
  221. MODULE_VERSION("MINI2440ADC 1.0");  
  222. MODULE_LICENSE("GPL");  


由于驅(qū)動(dòng)程序不同于應(yīng)用程序main函數(shù),因此讀者觀看以上程序的順序應(yīng)該如下所示:

首先執(zhí)行的代碼是__init adc_init函數(shù),它會(huì)被insmod加載進(jìn)內(nèi)核,當(dāng)然也可以在內(nèi)核初始化的時(shí)候加載,加載成功,應(yīng)用層訪問接口“/dev/adc”被創(chuàng)建;

其次,由于應(yīng)用層會(huì)首先打開“/dev/adc”設(shè)備,進(jìn)而操作ADC設(shè)備,因此需要查看adc_open函數(shù)做了什么。由于打開設(shè)備意味著要使用設(shè)備,所以在adc_open中注冊(cè)IRQ_ADC中斷資源;

最后,用戶會(huì)調(diào)用read函數(shù)讀取ADC轉(zhuǎn)換的值,會(huì)調(diào)用到adc_read。因此,在adc_read函數(shù)中需要設(shè)置好AIN0引腳的模擬輸入,并啟動(dòng)ADC,把讀取的任務(wù)交給adc_irq函數(shù)去完成,最后由adc_read函數(shù)把數(shù)據(jù)提交給應(yīng)用層。

如果使用insmod的方式加載,需要編寫Makefile函數(shù),如下:

  1. MODULENAME:= adc.o  
  2.    
  3. ifneq($(KERNELRELEASE),)  
  4. #call from kernel build system  
  5. obj-m      := $(MODULENAME)  
  6.    
  7. else  
  8. #KERNELDIR?= /lib/modules/$(shell uname -r)/build  
  9. KERNELDIR?= /work/system/linux-2.6.22.6  
  10. PWD       := $(shell pwd)  
  11. default:  
  12.        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  
  13. endif  
  14.    
  15. clean:  
  16.        rm -rf *.o *~ core .depend .*.cmd *.ko*.mod.c .tmp_versions module* Module* $(APPNAME)  
  17.    
  18. depend.depend dep:  
  19.        $(CC) $(CFLAGS) -M *.c > .depend  
  20.    
  21. ifeq(.depend,$(wildcard .depend))  
  22. include.depend  
  23. endif  

adc.c與Makefile文件放在同一目錄下,執(zhí)行make就可以了。Makefile中使用的編譯器的名稱為arm-linux-gcc,根據(jù)自己的情況修改即可。

編譯成功,在當(dāng)前目錄下得到adc.ko驅(qū)動(dòng)模塊,使用命令modinfo  adc.ko,獲取信息如下:

stu@stu-desktop:adc$modinfo adc.ko

filename:       adc.ko

license:        GPL

version:        MINI2440 ADC 1.0

description:    Mini2440 ADC Misc Device Driver

author:         Kevin Lee <www.>

srcversion:     901D02B007F9D53D9C54EA3

depends:       built-in,built-in,built-in,built-in,built-in

vermagic:       2.6.22.6mod_unload ARMv4

以上信息也是我們?cè)赼dc.c代碼中添加的,還有的是在編譯過程中得到的。

把a(bǔ)dc.ko文件放到開發(fā)板中,執(zhí)行insmod  adc.ko,看到如下信息則說明啟動(dòng)正常:

adc initialized!

并且可以查看/dev目錄下,已經(jīng)有adc設(shè)備文件

# ls  -l  /dev/adc

crw-rw----    1 0       0         10,  61 Jul 27 23:17 /dev/adc

1.4    可調(diào)電阻的測(cè)試程序

編寫測(cè)試程序adc_test.c文件,源代碼如下:

  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<fcntl.h>  
  4. #include<unistd.h>  
  5. #include<sys/types.h>  
  6. #include<errno.h>  
  7.    
  8. #defineDEVICE_NAME       "/dev/adc"  
  9.    
  10. intmain()  
  11. {  
  12.     int fd,ret,value;  
  13.    
  14.     fd = open(DEVICE_NAME, O_RDONLY);  
  15.     if(fd < 0) {  
  16.         perror("open ADC : ");  
  17.         exit(EXIT_FAILURE);  
  18.     }  
  19.    
  20.     ret = read(fd, &value, sizeof(value));  
  21.     if(ret < 0) {  
  22.             perror("read ADC:");  
  23.             close(fd);  
  24.             exit(EXIT_FAILURE);  
  25.     }  
  26.      
  27.     printf("read from ADC : %d\n",value);  
  28.     close(fd);  
  29.    
  30.     return 0;  
  31. }  


源代碼簡(jiǎn)單不做說明,編譯源代碼的命令:

arm-linux-gcc  -Wall -O2  adc_test.c  -o adc_test

arm-linux-strip  adc_test

拷貝adc_test文件到開發(fā)板,執(zhí)行命令./adc_test,顯示如下:

#./adc_test

readfrom ADC : 736

調(diào)節(jié)(旋轉(zhuǎn))電位器即轉(zhuǎn)動(dòng)變阻器,再次執(zhí)行./adc_test,顯示如下:

#./adc_test

readfrom ADC : 886

讀到的數(shù)值隨電阻值的變化而變化,由此說明驅(qū)動(dòng)及硬件工作正常。


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美午夜色视频国产精品| 亚洲第一视频少妇人妻系列 | 午夜日韩在线观看视频| 暴力性生活在线免费视频| 欧美午夜性刺激在线观看| 大香蕉久久精品一区二区字幕| 女人精品内射国产99| 在线亚洲成人中文字幕高清| 欧美一区二区三区高潮菊竹| 97人妻精品一区二区三区免| 国产免费自拍黄片免费看| 色婷婷视频国产一区视频| 国产欧美另类激情久久久| 国产精品一区二区高潮| 国产成人人人97超碰熟女| 视频在线观看色一区二区| 国产成人午夜av一区二区| 天海翼高清二区三区在线| 国产精品久久精品毛片| 国产精品欧美日韩中文字幕| 欧美国产极品一区二区| 成年午夜在线免费视频| 亚洲精品黄色片中文字幕| 国产精品人妻熟女毛片av久久| 国产精品午夜视频免费观看| 欧美亚洲三级视频在线观看| 日本少妇中文字幕不卡视频| 香蕉久久夜色精品国产尤物 | 久久这里只精品免费福利| 国产精品一区二区高潮| 亚洲丁香婷婷久久一区| 亚洲熟妇熟女久久精品| 精品国自产拍天天青青草原| 日本和亚洲的香蕉视频| 国内女人精品一区二区三区| 欧美成人免费一级特黄| 精品日韩国产高清毛片| 99久久国产精品亚洲| 国产成人精品资源在线观看| 丝袜人妻夜夜爽一区二区三区| 国产一二三区不卡视频|