ALSA / ASoC: วิธีโหลดอุปกรณ์ / ไดรเวอร์อย่างถูกต้อง


10

ฉันใช้ Buildroot เพื่อสร้างระบบ Linux (2.6.39.2) ในตัวสำหรับไมโครคอนโทรลเลอร์ NXP LPC3250

ตอนนี้ฉันกำลังพยายามทำให้ ALSA / ASoC ทำงาน แต่ฉันมีปัญหากับการทำให้โมดูลทำงานร่วมกัน (ฉันคิด!)

พื้นหลังสำคัญบางอย่าง:

คณะกรรมการฉันกำลังทดสอบกับเป็นศิลปินแบบฝัง 3250 V2 คณะกรรมการพัฒนาการ V2 แตกต่างจาก V1 เนื่องจากไม่มีหน้าจอ LCD แต่มีตัวแปลงสัญญาณเสียง I2S: NXP UDA1380 การสนับสนุนบอร์ดสำหรับ EA3250 V1รวมอยู่ในเคอร์เนลรุ่นLPCLinux นอกจากนี้ยังมีบอร์ดพัฒนาอื่นที่เรียกว่าPhytec 3250ซึ่งมีชิปตัวแปลงสัญญาณ UDA1380 เดียวกัน การกระจาย LPCLinux ยังสนับสนุนบอร์ด Phytec พร้อมกับชิปตัวแปลงสัญญาณเสียง จากสิ่งที่ฉันได้มองเห็นคณะกรรมการ Phytec 3250 มีตัวแปลงสัญญาณ UDA1380 บน I2C อยู่0x18 บนกระดาน EA3250 V2 ของฉัน, ตัวแปลงสัญญาณเสียงตั้งอยู่ที่อยู่ I2C 0x1a(ฉันตรวจสอบแล้วว่าชิปเปิดทำงานแล้วและฉันสามารถสื่อสารกับมันได้โดยใช้แพ็คเกจ I2C-tools มันตอบสนองต่อ i2cdetect และฉันสามารถอ่านการลงทะเบียนจากชิปได้อย่างถูกต้องโดยใช้ i2cget)

แก้ไขแหล่งที่มา:

ฉันต้องการแก้ไขไฟล์ไดรเวอร์ Phytec 3250 เพื่อเปลี่ยนที่อยู่ของชิปตัวแปลงสัญญาณ ฉันแก้ไขส่วนนี้ของlpc3xxx-uda1380.c :

static struct snd_soc_dai_link phy3250_uda1380_dai[] = {
       {
                  .name           = "uda1380",
                  .stream_name    = "UDA1380 Duplex",
  #if defined(CONFIG_SND_LPC32XX_USEI2S1)
                  .cpu_dai_name   = "lpc3xxx-i2s1",
  #else
                  .cpu_dai_name   = "lpc3xxx-i2s0",
  #endif
                  .codec_dai_name = "uda1380-hifi",
                  .init           = phy3250_uda1380_init,
                  .platform_name  = "lpc3xxx-audio.0",
         //EDIT// .codec_name     = "uda1380-codec.0-0018",  //EDIT//
                  .codec_name     = "uda1380-codec.0-001a",
                  .ops            = &phy3250_uda1380_ops,
          },
  };

หลังจากที่ฉันทำการเปลี่ยนแปลงฉันไปข้างหน้าและสร้างระบบอีกครั้งและทุกอย่างรวบรวมตกลง หลังจากบูทเข้าสู่ระบบฉันมีโมดูลดังต่อไปนี้ (นอกเหนือจากโมดูลหลักมาตรฐาน) ใน/lib/modules/2.6.39.2/kernel/sound:

 ./soc/codecs: snd-soc-uda1380.ko          <-- ASoC codec driver
./soc/lpc3xxx: snd-soc-lpc3xxx-i2s.ko      <-- ASoC DAI
               snd-soc-lpc3xxx-uda1380.ko  <-- ASoC machine driver
               snd-soc-lpc3xxx.ko          <-- ASoC platform driver

ตอนนี้ฉันจะผูกสิ่งเหล่านี้เข้าด้วยกันได้อย่างไร

เพียงแค่แทรกโมดูลด้วยmodprobeไม่ได้ให้อุปกรณ์กับ ALSA / ASoC ฉันไม่สามารถตรวจพบการ์ดเสียง นี่หมายความว่าฉันต้องสร้างอุปกรณ์ใหม่ที่เรียกว่าuda1380-codecที่อยู่0x1aและผูกมันไว้กับไดรเวอร์หรือไม่? ฉันได้ลองทำสิ่งต่อไปนี้
echo uda1380-codec 0x01a > /sys/bus/i2c/devices/i2c-0/new_device
และได้รับ
i2c i2c-0: new_device: Instantiated device uda1380-codec at 0x1a
แล้วฉันพยายามผูกไดรเวอร์กับอุปกรณ์
echo 0x1a > /sys/bus/i2c/drivers/uda1380-codec/bind
และได้รับ:
sh: write error: No such device

ฉันได้รับข้อผิดพลาดนี้สำหรับทุกสิ่งที่ฉันลอง! ฉันรู้สึกว่าฉันไม่ได้สร้างอุปกรณ์อย่างถูกต้องและจากนั้นฉันไม่แน่ใจว่าจะผูกกับไดรเวอร์ที่ถูกต้องได้อย่างไร

Nota Bene:

ฉันเล่นกับเมื่อคืนนี้และก็สามารถทำให้ ASoC ตื่นขึ้นมาและอย่างน้อยก็ไต่สวนการ์ด ฉันกำลังเล่นกับการผูกที่แตกต่างกันฉันเดา มันช้าและยากที่จะจำขั้นตอนของฉัน แต่อย่างน้อยฉันก็สามารถได้รับข้อผิดพลาดต่อไปนี้:

uda1380-codec 0-001a: asoc: failed to probe CODEC uda1380-codec.0-001a: -22
asoc: failed to instantiate card LPC32XX: -22

ฉันไม่สามารถสร้างข้อผิดพลาดนี้ได้อีก!

แก้ไข:

ฉันยืนยันว่าโค้ดที่ถูกแก้ไขของฉันกำลังถูกคอมไพล์ดังนั้นไดรเวอร์ควรจะพูดคุยกับที่อยู่ที่ถูกต้องในขณะนี้ หลังจากโหลดโมดูลด้วยตนเองเอาต์พุตของlsmodคือ:

Module                      Size  Used by    Not tainted
snd_soc_lpc3xxx_uda1380     2087  0 
snd_soc_lpc3xxx             3089  0 
snd_soc_lpc3xxx_i2s         4089  1 
snd_soc_uda1380            10865  0 
snd_soc_core               51549  4 snd_soc_lpc3xxx_uda1380,snd_soc_lpc3xxx,snd_soc_lpc3xxx_i2s,snd_soc_uda1380
snd_pcm                    52098  2 snd_soc_lpc3xxx,snd_soc_core
snd_timer                  15590  1 snd_pcm
snd_page_alloc              3021  1 snd_pcm
snd                        37286  3 snd_soc_core,snd_pcm,snd_timer

สิ่งนี้ดูถูกไหม?

และตารางอุปกรณ์ของฉัน:

# Audio stuff
/dev/audio      c       666     0       29      14      4       -       -       -
#/dev/audio1    c       666     0       29      14      20      -       -       -
/dev/dsp        c       666     0       29      14      3       -       -       -
#/dev/dsp1      c       666     0       29      14      19      -       -       -
#/dev/sndstat   c       666     0       29      14      6       -       -       -
/dev/mixer      c       666     0       29      14      0       -       -       -
/dev/snd        d       755     0       29      -       -       -       -       -
/dev/snd/controlC0      c       666     0       29      116     0       -       -       -
/dev/snd/pcmC0D0c       c       666     0       29      116     24      -       -       -
/dev/snd/pcmC0D0p       c       666     0       29      116     16      -       -       -
/dev/snd/seq    c       666     0       29      116     1       -       -       -
/dev/snd/timer  c       666     0       29      116     33      -       -       -

คุณควรอ่านเอกสาร ASoC แล้วถามในalsa-develรายการ (ซึ่งคุณจะได้รับแจ้งว่า 2.6.39 ล้าสมัยไปอย่างน่ากลัวและผู้ขายกระดานนั้นเป็นผู้รับผิดชอบการสนับสนุน)
CL

@CL ขอบคุณผู้ขายบอร์ดไม่รองรับตัวแปลงสัญญาณ UDA1380 ด้วย LPCLinux (ฉันได้ติดต่อพวกเขาไปแล้ว)ซึ่งเป็นสาเหตุที่ฉันพยายามแฮ็กข้อมูลด้วยตนเอง
dext0rb

ฉันโพสต์ไปalsa-develแล้วและไม่มีใครตอบกลับ (ที่ฉันสามารถบอกได้ - ฉันเกลียดรายชื่ออีเมลพวกมันแย่ที่สุดในการอ่าน) ตอนนี้กล่องจดหมายของฉันเต็มไปด้วยอึ ALSA และฉันก็ยังไม่มีความช่วยเหลือ ที่นี่ฉันจะไปอีกครั้งด้วยตัวฉันเอง ...
dext0rb

คำตอบ:


3

จำเป็นต้องแก้ไขไฟล์ของบอร์ดที่กำหนดอุปกรณ์แพลตฟอร์ม ฉันต้องการแก้ไขarch/arm/mach-lpc32xx/ea3250.c:

เพิ่มสิ่งนี้:

/*
 * Platform Data for UDA1380 Audiocodec.
 * As there are no GPIOs for codec power & reset pins,
 * dummy GPIO numbers are used.
 */
static struct uda1380_platform_data uda1380_info = {
    .gpio_power = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,10),
    .gpio_reset = LPC32XX_GPIO(LPC32XX_GPO_P3_GRP,2),
    .dac_clk    = UDA1380_DAC_CLK_WSPLL,
};

แก้ไขสิ่งนี้เพื่อรวมตัวแปลงสัญญาณ:

static struct i2c_board_info __initdata ea3250_i2c_board_info [] = {
        {   I2C_BOARD_INFO("uda1380", 0x1a),
            .platform_data = &uda1380_info,
        }, 
#if defined (CONFIG_LEDS_PCA9532)
        {
            I2C_BOARD_INFO("pca9532", I2C_PCA9532_ADDR),
            .platform_data = &ea3250_leds,
        },
#endif
#if defined (CONFIG_FB_ARMCLCD)
        {
            /* 8Kb Configuration EEPROM on display board */
            I2C_BOARD_INFO("ea_i2c_disp_cfg", LCDB_CONFIG_EEPROM_I2C_ADDR),
        },
        {
            I2C_BOARD_INFO("ea_i2c_video", LCDB_PCA9532_I2C_ADDR),
        },
#endif
#if defined (CONFIG_EEPROM_AT24)
        {
            I2C_BOARD_INFO("24c256", I2C_24LC256_ADDR),
        },
#endif
    };
#endif

ตอนนี้ฉันมีอุปกรณ์ทั้งหมด:

# cat cards
 0 [LPC32XX        ]:  - LPC32XX
                      LPC32XX
# cat devices
  2: [ 0- 0]: digital audio playback
  3: [ 0- 0]: digital audio capture
  4: [ 0]   : control
 33:        : timer

# cat pcm
00-00: UDA1380 Duplex uda1380-hifi-0 :  : playback 1 : capture 1

ฉันยังไม่สามารถaplayตรวจจับอะไรได้เลย แต่บางทีนั่นอาจเป็นปัญหาที่แตกต่างออกไป

แก้ไข: ใช่นั่นเป็นปัญหาที่แตกต่าง หมายเลขที่อยู่ด้านหน้าของอุปกรณ์ที่แสดงโดยcat devicesควรตรงกับหมายเลขอุปกรณ์รองในรายการ / dev / snd อุปกรณ์ของคุณ ทุกอย่างดูดีในตอนท้ายของ ALSA แต่ฉันไม่มีข้อมูล I2S ที่มาจาก LPC3250 ...

แก้ไข 2: แก้ไขแล้วแก้ไขแล้ว หากคุณไม่มีข้อมูล / นาฬิกา I2S ตรวจสอบให้แน่ใจว่าได้กำหนดค่าเอาต์พุต mux register อย่างถูกต้องเพื่อเชื่อมต่อหมุดเอาต์พุตกับอุปกรณ์ต่อพ่วง I2S !!!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.