找回密码
 注册
关于网站域名变更的通知
查看: 247|回复: 2
打印 上一主题 下一主题

有偿求ADI公司AD1933 LINUX平台驱动

[复制链接]
  • TA的每日心情
    擦汗
    2021-8-10 15:35
  • 签到天数: 140 天

    [LV.7]常住居民III

    跳转到指定楼层
    1#
    发表于 2021-12-23 11:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    有偿求ADI公司AD1933 LINUX平台通过SPI配置AD1933,通过SAI接口(4路数据)传输音频信号
      @7 u& h: t  p9 r

    该用户从未签到

    2#
    发表于 2021-12-23 13:54 | 只看该作者
    1、驱动源代码, K) `; B0 J6 @0 x2 V: ?
    1 r6 `$ I/ L$ a9 F! |/ R
    4 `$ Q* e  j% A8 h8 ^7 d# A
    #include <linux/module.h>! \0 g$ h0 j* Z' D
    #include <linux/kernel.h>
    : R8 ^1 N+ d  Z) M, j#include <linux/fs.h>
      q! x! Y) M8 E) C. a: B3 m8 x#include <linux/init.h>
    " I( G2 w% B- C#include <linux/device.h>( R  G$ E4 M' @# ?# w4 Q0 h
    #include <linux/miscdevice.h>
    ) R. Y  ^. k: {- Z#include <linux/delay.h>
    ; W$ Z% D! @% `8 T8 o#include <linux/mm.h>
    . ~+ h% G7 ~8 h#include <asm/irq.h>
    $ G/ P8 P0 O& c6 T2 d5 O#include <asm/arch/regs-timer.h>( s4 c" @$ J) v- d+ a2 E9 |# b
    #include <asm/arch/regs-adc.h>
      L9 A% q+ C* w6 T6 `#include <asm/arch/regs-gpio.h>- W7 c0 c+ {4 `4 E  p
    #include <asm/arch/map.h>3 O0 Q+ j% t3 o, a0 Q& C7 F
    #include <asm/arch/regs-irq.h>: \  \0 e! X) |  y$ f6 u% d( r
    #include <asm/io.h>& Q" w' P5 j7 v* a2 O( a) b2 w
    #include <asm/hardware.h>9 r5 ~! B# l( o  \* W2 W
    #include <asm/uaccess.h>
    6 S! \- C. X  C2 Y0 @; O0 B#include <asm/system.h>
      a% f2 f' U( I* C. D/ C! J#include <linux/errno.h>
    7 A$ t1 ]8 n) E$ b#include <linux/slab.h>
    5 J- W& }5 ?, J7 e8 u#include <linux/input.h>
    2 X+ K: D( y4 ?3 Y; c2 [#include <linux/serio.h>
    0 y. t$ A) [& q; F7 h. g' H#include <linux/clk.h>
      {5 d% s. v$ T; Z, K9 S) E#include <linux/cdev.h>" t1 j0 z- o$ f' v

    0 }( s, R8 ^% ~

    ; H5 v9 F8 [% m/ b5 t9 \
      V, P, l2 o4 w/ y

    5 H# T0 n: P( H3 J7 {9 @#define ADC_WRITE(ch, prescale)    ((ch) << 16 | (prescale))  Y. X, @8 _: l  v8 C; j7 D

    - Z8 @9 s$ h4 m: e, ]% {' q

    ! [! o3 P: K9 O: {( {" X, y#define ADC_WRITE_GETCH(data)    (((data) >> 16) & 0x7)
    0 j9 \8 w9 c8 _) D! N3 N3 W#define ADC_WRITE_GETPRE(data)    ((data) & 0xff)
    " N, l% D( \- S4 \" u
    : H  m) H0 K) [  J/ a2 O1 b: Q; {/ V+ U* [

    3 ^5 t, X% M7 |) J8 K5 v#define DEVICE_NAME    "adc"
    6 ]" R$ v+ X" P. P9 I7 L6 B) ]$ T
    5 W/ z8 A1 Q# V. O5 q, R

    3 ^, e6 X. L  Y/ wstatic void __iomem *base_addr;3 e5 B# d/ ~6 x4 \1 O5 W

    : z! |3 S4 m, U( E( S3 n$ ~
    - V" N( h6 b) N! z" i8 o
    typedef struct {                    //adc转换的设备结构体
    5 t1 \, Y+ [, y8 a    wait_queue_head_t wait; //等待队列
    7 h. ~& C' c9 L5 O    int channel;            //ADC转换通道) ]' ?7 U; h3 A0 ]% \; b
        int prescale;
    9 V. V$ |% w! t7 F1 a; u. {. h}ADC_DEV;7 z6 W5 g6 G* _

    : P" G! O! \; I$ b' g
    3 r4 d" q$ h+ o! C
    DECLARE_MUTEX(ADC_LOCK); //定义互斥信号量4 Q# b( V+ Z/ D8 ~
    static int ADC_OK = 0;& G# P" W$ m- @* D, _5 m1 q: x0 `% A; H

    3 D$ \! A6 r" y: i# J

      z8 u- O* V2 p, mstatic ADC_DEV adcdev;
    7 b* q5 N$ t& o) k" Bstatic volatile int ev_adc = 0;
    , G8 u6 o, b" l, R  F' Xstatic int adc_data;$ D- _6 v8 X' r4 _$ p- ?
    7 W4 n9 F4 M3 \% t0 ^  q4 P

    . L! g, f8 |+ C$ H4 s. B" e, J; lstatic struct clk    *adc_clock;/ y6 {- f  _; @2 C

    & N8 \9 N0 ]5 k7 W

    5 |( m' _9 {2 c0 o9 g#define ADCCON     (*(volatile unsigned long *)(base_addr + S3C2410_ADCCON))    //ADC control5 p  ]0 @8 s) S% G
    #define ADCTSC     (*(volatile unsigned long *)(base_addr + S3C2410_ADCTSC))    //ADC touch screen control
    ) g+ k& J' b' H6 }' y( j#define ADCDLY     (*(volatile unsigned long *)(base_addr + S3C2410_ADCDLY))    //ADC start or Interval Delay2 G/ N" U8 I! I; g
    #define ADCDAT0     (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT0))    //ADC conversion data 0& C/ m$ v( Q/ x  N
    #define ADCDAT1     (*(volatile unsigned long *)(base_addr + S3C2410_ADCDAT1))    //ADC conversion data 1+ S. D; B2 q* ?8 H' c
    #define ADCUPDN     (*(volatile unsigned long *)(base_addr + 0x14))        //Stylus Up/Down interrupt status# v4 i& ^1 }& `8 i# b+ A3 S: H
    , `8 n( N( ~. _

    * M: a8 M% ^, l6 f# `4 Q- h#define PRESCALE_DIS        (0 << 14)
    0 T7 S$ U5 ?( _8 H& K! V2 _#define PRESCALE_EN        (1 << 14)   //使能预分频
    ' P/ _, y. y- t$ \. I#define PRSCVL(x)            ((x) << 6)//设定的预分频值8 r/ Y  r3 Q+ k, R. J2 k$ u" B
    #define ADC_INPUT(x)        ((x) << 3)  //选择ADC转换通道- @0 U' i  |) |3 U0 ?0 l" y
    #define ADC_START        (1 << 0)   //    启动ADC转换
    5 C6 [! d1 c  x#define ADC_ENDCVT        (1 << 15)
    $ l3 D+ z2 Q" N! K1 G% J1 ^9 M* K; q

    & i/ F! Y5 l. F6 {, R//AD转换中断处理函数
    4 k& o% Q* x% F( {1 mstatic irqreturn_t adcdone_int_handler(int irq, void *dev_id)7 d8 V3 l8 Z8 v5 a
    {undefined
    : y7 N2 S) q+ w1 X6 m    if (ADC_OK)
    4 ~! P  p5 c: d% A, _    {undefined) f+ e; O, O( |/ z/ a
            adc_data = ADCDAT0 & 0x3ff; //提取AD转换后的数据
    0 r) l1 r) |  z
      H5 B( O9 L* M( r
    2 I$ Y5 z2 Q0 Z/ b) W6 s4 h5 f) X# f
            ev_adc = 1;  //转换结束唤醒等待的进程8 s  M/ y" T: f: i+ r' T6 H
            wake_up_interruptible(&adcdev.wait);# Z& d+ B. E' U% G# n
        }) N- T$ l- B8 x: q, n
    8 C! {+ G6 c! b5 n

    # r' [2 w+ @4 n0 Q9 s    return IRQ_HANDLED;% R* Z' X( w3 _6 }6 E/ M2 R* m
    }3 G1 A( X% [% u2 j5 q* m* `
    3 s; ?1 y6 I8 c- ~

    + B( }# [* A8 i- X4 \$ X$ }static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
    8 n4 x0 q' T$ P{undefined  ?: E8 D4 I" X" B
        char str[20];$ I* n4 ?. w: c5 x( g
        int value;* |- b8 j. L& g4 l' c9 t
        size_t len;
    & t% [# T) s( Q( E4 S$ F    if (down_trylock(&ADC_LOCK) == 0) //获得信号量 :获得不到信号量不会阻塞
    ( V5 s& ^1 c" V, X    {undefined/ t1 w# {  m4 ~8 `4 x0 ~
            ADC_OK = 1;//启动AD转换
    # n, C* P. C9 w  X; M6 ^( S. f* q- p        ADCCON = PRESCALE_EN | PRSCVL(adcdev.prescale) | ADC_INPUT((adcdev.channel)) ;7 e, `5 w6 O+ ]& i0 o
            //使能预分频    设置预分频值  选择ADC转换通道4 P% u* m% l1 }3 R2 n
            ADCCON |= ADC_START; //启动AD转换
      w7 q+ h: b1 L0 l        
    % m+ Y4 {# A2 h        wait_event_interruptible(adcdev.wait, ev_adc);  //阻塞等待AD转换
    2 \1 i# s2 s0 b! M6 O6 j) F
    / C6 E% E- F2 [% _

    # l$ M$ \- c3 s# _4 y& C7 g" ?        ev_adc = 0;//清除转换标志位
    $ {  }( K6 ~0 X% g/ M7 N0 K( U* I' I% J

    ( L* P  F; @+ R. W+ O! U, W, Y//        printk("AIN[%d] = 0x%04x, %d\n", adcdev.channel, adc_data, ADCCON & 0x80 ? 1:0);1 I% v# T& `3 f0 N( C( U) B% O
    3 P: i. A% W7 i5 ?" C

    ) ]0 t1 i: m7 ~$ t+ r" ]# {! q        value = adc_data; //AD转换的数据3 |# j% q; c: H9 W6 b; U! D& Z
            sprintf(str,"%5d", adc_data);//数据转换/ w" \, A: M0 ~4 Q: X5 j  g
            //copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));. [$ v+ }0 b2 i2 O* e" t

    7 a8 g3 b2 D* B1 M( d- u
    ! u3 q5 K/ }- L2 q
            ADC_OK = 0;
    * A/ q) u% h: q# i. y        up(&ADC_LOCK);//释放信号量
    & F3 E1 s/ n" @: o& Z5 C* t9 u# b    }
    + x, S' S% |3 W    else
    ; {- p0 [  V/ \: o- z    {undefined  o7 t' E5 l% y
            value = -1;6 ~/ w/ y  W7 z( H1 J3 M( \
        }
    % T* @8 z4 v- f1 S7 Y( B5 E- j8 D1 A$ {3 z

    0 E* b& X- r4 x* h+ r& G    len = sprintf(str, "%d\n", value);7 a5 W1 r: R4 n3 `- u3 [" U
        if (count >= len), u3 ]1 x: s: `& [+ Y
        {undefined9 Q1 `2 ^* ~: w" m. P1 [1 E8 p: Q
            int r = copy_to_user(buffer, str, len); //把AD转换数据送回用户空间
    ' J9 C# |! N  a2 \- j        return r ? r : len;; H/ y  `* e# [" {9 ^3 `; Z2 Q. {
        }4 ]! }9 X) r8 V
        else* y  L$ W# H, R1 r6 u
        {undefined
    * p8 Z) ^2 J# r8 P3 ~2 v        return -EINVAL;
    " R* \8 M5 r" ]2 i; ?    }3 n+ w' O2 F' F
    }1 ^6 B+ ?3 [; A) h& c

    4 A3 }& m7 F+ J9 p& l6 ]0 P

    ) V. j+ K1 F. {3 fstatic int s3c2410_adc_open(struct inode *inode, struct file *filp)
      U6 N! R& a2 G: _, V8 U) Q{undefined+ U1 i8 h& p6 W5 K( i' A$ u+ ~
        init_waitqueue_head(&(adcdev.wait));  //初始化等待队列
    # `1 Q8 }3 m* U9 ]# i
    3 P2 [( c/ h' [2 x

      T( n( S8 @3 J    adcdev.channel=0;        //选择ADC转换的通道    //AIN 0 or (0~7)
    ; n( W. E) l; f    adcdev.prescale=0xff;          //AD转换延时
    , o) M0 ~! M4 ]+ t0 t0 M; m: L8 u
    8 I) t7 y3 C) E8 p
    ! s( p  ]& U; N3 F5 |$ U
        printk( "ADC opened\n");) _5 z; h# s& d3 b1 |+ i0 Q
        return 0;
    3 A6 n, y- ^/ V, I6 a1 e0 {/ W}! g' Z: l, }( W* l/ O

    6 u' a9 X& ^" p6 x4 w  q

    ) p9 H6 K& ]7 m. y( E0 l% ~static int s3c2410_adc_release(struct inode *inode, struct file *filp)
    ; H* v# U4 Z' V! }* e{undefined: F" y% |5 Q# F+ j
        printk( "EmbedSky-ADC closed\n");
      k) E2 d4 [6 x+ y  |5 A. I/ K7 E    return 0;
    : C% x- t9 g1 J# A% I  G( h2 u' \}! s) R0 ~$ ]2 {3 e7 |

    9 P# {4 Z& w# J
    # l; f2 I- |" @5 z
    static struct file_operations Adc_fops = {undefined
    1 H9 c2 V. ?+ A4 K% n. {    owner:    THIS_MODULE,
    # v4 A6 z: C. |' w5 B    open:    s3c2410_adc_open,( R. n  C0 r& M+ A; V6 g
        read:    s3c2410_adc_read,   
    ! M/ {( a# N4 D; q" z: Z    release:    s3c2410_adc_release,* D# b+ L8 l0 q" X
    };
    7 O9 b: G5 n, Y+ ^* o- g) r+ A! d: H! }, P( E  T
    ; X2 f, z" a- h( n. G+ x
    static struct miscdevice misc = {undefined' G1 R- A# y) ^) I! J4 v
        .minor = MISC_DYNAMIC_MINOR,6 Y  e5 _3 U; B: p# \9 ?
        .name = DEVICE_NAME,; N: s* [" X7 Q, a
        .fops = &Adc_fops,
    . q# z4 a5 f/ Q, \- A, V};! z/ P5 D. a+ N1 q

    5 P6 Z9 X" s& h
    9 H3 w  }- `5 [& {9 M5 \
    static char __initdata banner[] = "S3C2440 ADC\n";
    - ~! j6 Y- f* P: X* ?' y) s2 o- G
    ( X1 e, d& g1 G1 j. a

    - k$ e% V9 ~2 [& Bstatic int __init Adc_init(void)
    0 A. u& e( o/ C, H, W{undefined
    2 K0 y* c$ M8 a' _( W' q/ g    int ret;
    + R* o* B' \( @; z  T( [7 a( G    printk(banner);
    4 V+ A1 I8 X: y1 G. s: u
    & C; v' W8 e+ p' @

    . \& F3 y3 c- {( Z; d9 ]    base_addr=ioremap(S3C2410_PA_ADC,0x20);//映射把物理地址映射为虚拟地址$ E. Z# U# ?+ w
        if (base_addr == NULL)  //返回值检测' b* c! B# O/ E5 u
        {undefined: D: b8 J7 K* ?9 `# l
            printk(KERN_ERR "Failed to remap register block\n");+ b& C# @- ?9 K/ ^& ]. E5 W1 @; c
            return -ENOMEM;
    # V5 N0 S6 ~; t! v    }; p% o" z- {( x& |, E
    ) L& C- V/ ~$ L  h* B9 H3 D) U

    3 ], |/ m6 \  r/ U# R  V    adc_clock = clk_get(NULL, "adc"); //获得ADC的时钟
    + g; T( ]; L5 k* B, d6 p. Z: K- s    if (!adc_clock)
    " p1 Z) L/ Q; R3 M7 p) M    {undefined+ S. g/ [4 h! n4 C: ]  \8 X  ~
            printk(KERN_ERR "failed to get adc clock source\n");: W/ o% Q! h' W/ w! \4 ^0 ?2 C
            return -ENOENT;
    " e4 J1 E7 |: o0 ]8 s' V8 r4 T    }
    2 V& @& t) v! N$ b5 q    clk_enable(adc_clock);//使能ADC的时钟
    : C/ J8 Q: E# S    3 D1 L1 \# H9 d( t( O5 Q9 F
        /* normal ADC */6 A6 _" P; l6 [. [
        ADCTSC = 0;//不使用触摸屏; [; X5 d% t# C

    - d5 L1 c! z: G5 |* e7 U
    . P# f7 ]$ i4 d2 y
        ret = request_irq(IRQ_ADC, adcdone_int_handler, IRQF_SHARED, DEVICE_NAME, &adcdev);//注册中断: z" [1 C3 X- A0 f/ \2 C
        if (ret)
    ! g; a. g5 x2 f8 X- f) G    {undefined; T6 Y% n* w/ \$ N9 |; O6 e$ ^$ O
            iounmap(base_addr);3 s" Z* V5 U1 V" E
            return ret;
    4 ~% T) B( `' G    }
    & A8 c, P2 U7 Z) t( F* q/ [4 W; U
    , S" i, Y5 P: X# \8 z4 q$ ]
    0 [* O- O6 N* ~! P9 ?& \
        ret = misc_register(&misc);//注册一个混杂设备
    $ h; h2 S% a+ }8 A8 @# {- G% v$ F7 S3 \' v: \
    4 y3 h8 w, o' M/ c3 X: U
        printk(DEVICE_NAME " initialized\n");  ^& @0 J0 y, F4 M1 d4 m
        return ret;
    ' S# |9 T% d! h/ F+ `}
    % g5 V, k4 F3 ^3 U) n: r3 n
    4 k9 L  ?* K( ^# ]0 g

    6 H. ^1 v3 E9 E$ A, fstatic void __exit Adc_exit(void)/ f4 I9 ?9 a$ y+ Y' {$ i6 G1 L
    {undefined
    * I1 \1 [. Z5 W3 b. {$ ^    free_irq(IRQ_ADC, &adcdev);//注销中断! {4 F  ~/ f& B
        iounmap(base_addr);   //解除映射) O& P* A% g7 P3 G0 u* u. e0 u
    ( w+ f8 A- F) D0 [# b3 l, `% I

    7 F+ N. [" K) y8 y3 C7 i) P    if (adc_clock)
    - L5 {- T' z  Z4 m* \9 H2 J    {undefined" ^/ R% o5 U( s  x0 _/ a% M/ i: }
            clk_disable(adc_clock);//关闭adc转换的时钟
    - r, e2 [( Y! J& x8 A        clk_put(adc_clock);     
    2 |- b) J/ b/ i& s  Q8 m        adc_clock = NULL;0 c# p% L. S* U7 X  Q' J9 b
        }
    4 C. ~. P7 ~: y6 Y2 F* {0 P! V! O7 B( `! O/ v- f) Z

    1 Q0 G1 _5 Q* v1 ^    misc_deregister(&misc);//注销混杂设备# u6 p* d5 q& f' K' b+ t6 O9 q/ _
    }
    % ?0 E/ j6 n& I* W
    - D: f; y1 N' N

    2 k# z6 Z7 d0 F, P0 `5 q4 CEXPORT_SYMBOL(ADC_LOCK);
    # O! m5 s8 Z& {( g
    # u& [) R! O+ |

    % [) e& J9 C) g4 ^: S# Q/ D6 T! D4 P) d. M- M' R

    0 F% M5 X! n/ G6 Hmodule_init(Adc_init);
    * L* A1 C6 M9 b8 Z2 S% ^" Mmodule_exit(Adc_exit);% D8 u- C8 L9 o* Y: h+ F4 `4 @
    ( ~5 S' ~1 D7 a3 p
    - R3 I: ?% ]) g/ T. S- x7 P

    6 T& x- A, \/ e1 r

    # J! x5 {, b" C: g  v" \2 LMODULE_LICENSE("GPL");                    
    3 f0 o6 z2 @5 E  T! B2、应用程序; B& e- a% Q  ^/ v4 \

    ; ]0 x0 e! c! }" H* ]

    & I3 b" O2 M+ W; w* M9 `! W#include <stdio.h>/ ^' r- V! J* `' w! y
    #include <stdlib.h>1 }8 X( g* N7 z4 p7 N8 H7 s
    #include <unistd.h>
    . S5 H/ }% T- y  J- H8 J#include <sys/ioctl.h>1 z9 s8 \- N& D9 n9 O
    #include <sys/types.h>3 Z( T) i5 y. ~* y0 X4 I
    #include <sys/stat.h>
    $ Q& @0 A1 O* J3 Y/ z# o#include <fcntl.h>
    3 ?( U" d+ _8 s$ {6 l6 I#include <sys/select.h>
    % z) t$ ~5 M7 u: B#include <sys/time.h>& X: m7 F9 {! V1 R
    #include <errno.h>  m6 v5 G# I; k# d1 O
    #include <linux/input.h>) z8 y* C: `8 q. x; N" T+ e
    int main(void)
    1 `1 J1 b  u4 g8 e+ `$ q* U{undefined' ^& y1 `' {* k8 u2 A
        int adc_fd;: e- a% m# m( Q+ u* s& Y
        int count;% m+ t3 O9 Z/ G
        char adc[6];, P3 M9 D% W7 S# }7 ^1 i5 n
        adc_fd = open("/dev/adc", O_RDWR); //以阻塞的方式打开设备文件: r+ |, o- a7 Q" D' _
        if (adc_fd < 0) {undefined
    8 S  \8 \" a. E9 G0 b; }4 w        perror("open device adc_fd");* I" z0 G: f( V, f( j6 W
            exit(1);9 R2 o) f0 `  l& o- F% Z
        }& f  \9 ?+ e- N  W
    ' V# K7 N% [# R) G3 i( ^
    4 R. `' C/ l/ j2 S2 d/ q+ L
        for (;;) {undefined# ?- @; y. g# g; ~$ x
            count = read(adc_fd,&adc,sizeof(adc));
    9 M" ?3 U: m0 z3 ~        adc[count]='\0';
    3 S. t' ^) |/ v+ o; f- k4 j2 c        printf(" adc = %s\n", adc);8 z* u" f- ^0 f! [% N' `2 M
                    sleep(2);//2秒钟采样一次
    1 `3 ~- e7 X& t7 z% ?! U5 F0 L+ {) E/ H; b7 T
    7 n& {; W" U: f1 g& v5 m9 ~
        }8 b0 V) m, l7 T% L& r3 V
    5 e5 m1 l# w: D) M
    0 j8 o7 H0 {* w) J
        close(adc_fd);; }; g! Q$ m* X0 z- m5 v2 D
        return 0;
    ; \0 d3 \; t& @  x}
    % `$ l7 K( |% i: E* ^: v- `希望能帮到你
    ! \0 f, T* c' c2 E( x" {) c  b- |* Y/ U2 ^8 ?

    点评

    可是我没有那些宏定义与头文件啊?  详情 回复 发表于 2021-12-23 16:28
  • TA的每日心情
    擦汗
    2021-8-10 15:35
  • 签到天数: 140 天

    [LV.7]常住居民III

    3#
     楼主| 发表于 2021-12-23 16:28 | 只看该作者
    damengshu 发表于 2021-12-23 13:54
    * p  v+ b% d: H1、驱动源代码
    : {6 w# n( F/ \5 ~
    可是我没有那些宏定义与头文件啊?3 Z- H8 T% {6 R9 t; W& k% r
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-8-1 09:07 , Processed in 0.140625 second(s), 27 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表