ALSA/ASoC: 장치/드라이버를 올바르게 로드하는 방법은 무엇입니까?

ALSA/ASoC: 장치/드라이버를 올바르게 로드하는 방법은 무엇입니까?

저는 Buildroot를 사용하여 NXP LPC3250 마이크로컨트롤러용 임베디드 Linux(2.6.39.2) 시스템을 구축하고 있습니다.

지금은 ALSA/ASoC를 시작하고 실행하려고 노력하고 있지만 모듈이 함께 작동하도록 하는 데 몇 가지 문제가 있습니다. (제 생각에는!)

몇 가지 중요한 배경:

제가 테스트하고 있는 메인보드는Embedded Artists 3250 V2 개발 보드. V2는 LCD 화면이 없다는 점에서 V1과 다르지만포함한다I2S 오디오 코덱: NXP UDA1380. EA3250에 대한 마더보드 지원V1포함 된LPCLinux커널 버전. 라는 다른 개발 보드도 있습니다.파이텍 3250, 동일한 UDA1380 코덱 칩이 포함되어 있습니다. LPCLinux 배포판은 Phytec 보드와 오디오 코덱 칩도 지원합니다. 내가 아는 한 Phytec 3250 보드의 I2C 주소에는 UDA1380 코덱이 있습니다.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

시도한 모든 것이 이 오류를 받았습니다! 장치를 올바르게 생성하지 않았다는 느낌이 들고 올바른 드라이버에 바인딩하는 방법을 잘 모르겠습니다.

노타 베니:

어젯밤에 이걸 가지고 놀다가 어떻게든 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      -       -       -

답변1

플랫폼 장치를 정의하는 보드 파일을 편집해야 합니다. 수정해야 할 사항 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 측에서는 모든 것이 괜찮아 보이지만 LPC3250의 I2S 데이터가 없습니다...

편집 2: 해결됨 해결됨. I2S 데이터/클럭이 없는 경우 출력 핀을 I2S 주변 장치에 연결하도록 출력 멀티플렉서 레지스터를 올바르게 구성했는지 확인하십시오!

관련 정보