Linux/Kernel Driver

Multimedia 처리 드라이버 개발: Audio Codec 드라이버 포팅 및 테스트

임베디드 친구 2025. 4. 1. 09:19
728x90
반응형

Multimedia 처리 드라이버 개발: Audio Codec 드라이버 포팅 및 테스트

안녕하세요! 오늘은 Rockchip RK3399 플랫폼에서 Audio Codec 드라이버를 포팅하고 테스트하는 방법에 대해 다뤄보겠습니다. Embedded Linux Kernel에서 멀티미디어 처리 드라이버를 작성하고 포팅하는 것은 시스템의 성능과 기능에 큰 영향을 미치는 중요한 작업입니다.

이 글에서는 Audio Codec 드라이버를 개발하고, RK3399 플랫폼에 포팅한 후, 이를 테스트하는 과정을 단계별로 설명하겠습니다.


1. Audio Codec 드라이버 개요

Audio Codec은 아날로그 오디오 신호를 디지털 신호로 변환(ADC)하거나 디지털 신호를 아날로그 신호로 변환(DAC)하는 하드웨어 장치입니다. Linux Kernel에서는 ASoC (ALSA System on Chip) 프레임워크를 이용해 Audio Codec을 관리할 수 있습니다.

주요 구성 요소:

  • Codec Driver: Audio Codec 하드웨어를 제어합니다.
  • Platform Driver: CPU와 Codec 간 데이터 전송을 관리합니다.
  • Machine Driver: Codec, CPU, Platform을 연결하고 초기화합니다.

2. 드라이버 포팅 준비

2.1 필요 도구 및 환경 설정

드라이버 포팅에 필요한 기본 환경은 다음과 같습니다:

  • 개발 환경: Ubuntu 20.04 이상
  • 크로스 컴파일러: aarch64-linux-gnu-gcc
  • 소스 코드: Linux Kernel 소스 (RK3399 SDK 포함)
  • 보드: Rockchip RK3399 개발 보드
  • Audio Codec: WM8960 (예제 Codec)

2.2 Kernel Configuration

make menuconfig 명령어를 사용해 Kernel을 설정합니다.

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

다음 항목을 활성화합니다:

  • Device Drivers -> Sound card support -> Advanced Linux Sound Architecture
  • ALSA for SoC audio support
  • SoC Audio for RK3399 platforms
  • Codec driver for WM8960

설정을 저장한 후, Kernel을 다시 빌드합니다.

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules_install

3. Audio Codec 드라이버 작성

3.1 Codec Driver 작성

WM8960 Codec 드라이버는 이미 Kernel 소스에 포함되어 있지만, 최신 커널 소스에서 변경되었을 가능성이 있으니 실제 환경에 맞는 커널 소스를 확인하세요. Machine Driver에서 이를 호출해야 합니다. 다음은 Machine Driver의 예제 코드입니다:

#include <linux/module.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>

static struct snd_soc_dai_link rk3399_wm8960_dai_link = {
    .name = "WM8960",
    .stream_name = "WM8960 Playback",
    .cpu_dai_name = "ff880000.i2s",
    .codec_dai_name = "wm8960-hifi",
    .platform_name = "ff880000.i2s",
    .codec_name = "wm8960.0-001a",
    .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM,
};

static struct snd_soc_card rk3399_wm8960_card = {
    .name = "rk3399-wm8960",
    .owner = THIS_MODULE,
    .dai_link = &rk3399_wm8960_dai_link,
    .num_links = 1,
};

static int rk3399_audio_probe(struct platform_device *pdev)
{
    struct snd_soc_card *card = &rk3399_wm8960_card;
    card->dev = &pdev->dev;
    return devm_snd_soc_register_card(&pdev->dev, card);
}

static const struct of_device_id rk3399_audio_dt_ids[] = {
    { .compatible = "rockchip,rk3399-wm8960", },
    {}
};
MODULE_DEVICE_TABLE(of, rk3399_audio_dt_ids);

static struct platform_driver rk3399_audio_driver = {
    .driver = {
        .name = "rk3399-wm8960",
        .of_match_table = rk3399_audio_dt_ids,
    },
    .probe = rk3399_audio_probe,
};
module_platform_driver(rk3399_audio_driver);

MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("RK3399 WM8960 ASoC Machine Driver");
MODULE_LICENSE("GPL");

4. Device Tree 설정

arch/arm64/boot/dts/rockchip/rk3399.dtsi 파일에 WM8960 관련 노드를 추가합니다:

&i2c1 {
    status = "okay";
    wm8960: wm8960@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
    };
};

&i2s1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2s1_mclk>;
    assigned-clocks = <&cru SCLK_I2S1_MCLK>;
    assigned-clock-parents = <&cru PLL_AUDIO>;
    assigned-clock-rates = <12288000>;
};

5. 테스트

5.1 드라이버 로드

Kernel과 Device Tree를 빌드하고 RK3399 보드에 업로드한 뒤 드라이버를 로드합니다:

insmod snd-soc-rk3399-wm8960.ko

5.2 테스트

aplayarecord 명령어를 이용해 오디오를 재생하고 녹음합니다:

aplay -D hw:0,0 test.wav
arecord -D hw:0,0 -f cd test_record.wav

오디오가 정상적으로 출력되고 녹음되면 드라이버가 성공적으로 동작한 것입니다.


6. 결론

이번 포스팅에서는 Rockchip RK3399 플랫폼에서 Audio Codec 드라이버를 포팅하고 테스트하는 과정을 살펴보았습니다. 멀티미디어 처리 드라이버 개발은 복잡하지만, ASoC 프레임워크와 올바른 설정을 통해 효율적으로 구현할 수 있습니다.

반응형