S3C2440 sound card driver transplantation, testing and madplay playback of mp3 files (31)

Publisher:雷电狂舞Latest update time:2020-07-07 Source: eefocusKeywords:S3C2440 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

In this section, you will learn:


Analysis of OOS sound card system in Linux

Modify the control part of s3c2410-uda1341.c and transplant the wm8976 sound card

Play MP3 using madplay app

Common English words in this section:


volume: volume, dsp: digital signal processing, mixer: mixer, unit: unit, individual 

1. Three elements of sound


Sampling frequency


The audio sampling rate refers to the number of times a recording device samples a sound signal in one second. Commonly used sampling rates are:


8KHz --- The sampling rate used by telephones, which is clear enough for human speech

22.05KHz --- Sampling rate used in radio broadcasts

32KHz ---sampling rate used by miniDV digital video and DAT

44.1KHz --- Audio CD, also commonly used in MPEG-1 video (VCD, SVCD, MP3) sampling rate

48KHz ---The sampling rate used by digital sound for miniDV, digital TV, DVD, DAT, movies and professional videos

50KHz --- Sampling rate used by commercial digital recorders

96KHz --- The sampling rate used by BD-ROM (Blu-ray Disc) audio tracks and HD_DVD (High Definition DVD) audio tracks, etc.

The sampling frequency IISLRCK of the 2440 development board can reach up to 96KHz, which meets many common sampling occasions, as shown in the following figure:


Quantization bit number


Refers to the number of digital signals transmitted at each sampling point, as shown in the figure below, where the blue line represents the analog signal and the red line represents the digital signal. The higher the quantization bit, the closer the digital signal is to the original signal and the better the sound quality.


The general number of quantization bits is:


8 bits: divided into 256 times;

16 bits: divided into 65536 times, which has reached the CD standard;

32 bits: divided into 4294967296 times, rarely used

The 2440 development board only supports 8-bit and 16-bit, as shown below:


LRCK is the sampling frequency. When LRCK is low, it means that the sampled data transmitted is the left channel. When LRCK is high, it means that the sampled data transmitted is the right channel. At each sampling point, SD (serial data) can transmit 8-bit or 16-bit digital signals (transmitted from low to high).


Number of channels


There are often mono and stereo (some are also processed so that two speakers can output the sound of the same channel), and stereo can better feel the spatial effect, but the amount of data is doubled


Therefore, the amount of sound data per second (bytes/s) = (sampling frequency x number of quantization bits x number of channels)/8;


2. WM8976 sound card hardware analysis


A sound card is a multimedia board responsible for recording, broadcasting, adjusting volume, and sound synthesis.


The sound card used in this section is the WM9876 sound card that comes with the 2440 board.

When we play sound, we pass the digital signal to the I2SDO pin, and the sound card decodes it and generates an analog signal to the speaker/headphone.


When we record, the sound card obtains the analog signal from the microphone and encodes it into a digital signal on the I2SDI pin.


VM8976 interfaces are divided into two types: I2S interface (provides audio reception and transmission) and control interface (controls volume, enables each output channel, etc.)


The pins related to the IIS interface are as follows:


MCLK: Master/system clock input provided by the host to the decoding chip

BCLK: Serial clock signal provided by the codec chip (Audio bit clock output)

I2SLRCK: sampling frequency signal, when it is low level, the left channel signal is sampled, when it is high level, the right channel signal is sampled

I2SDI: ADC data input

I2SDO: DAC data output

As shown below:

The pins related to the control interface are as follows:


CSB/GPIO1: 3-wire control data enable pin

SCLK: 3-wire/2-wire always pin

SDIN: 3-wire/2-wire data input and output pin

MODE: 3-wire/2-wire control selection. When MODE is high, it means 3-wire control. When MODE is low, it means 2-wire control, as shown in the following figure:


The other pins are as follows:


R/LOUT1: Audio left/right output channel 1, external headphone jack

R/LOUT2: Audio left/right output channel 2, not connected

OUT3: Mono output channel 3, not connected

OUT4: Mono output channel 4, not connected

LIP/LIN: audio input channel, external microphone

 

So what is the difference between the control pins of 3-wire and 2-wire?


3-wire control:


As shown in the figure below, 3-wire control requires 16 bits of data to be transmitted in each cycle (7-bit register address + 9-bit register data). After the transmission is completed, a rising edge is given to CSB to complete the data transmission.


2-wire control:


As shown in the figure below, 2-wire control is the I2C communication method.


In this section, the MODE pin of WM8976 is high, so it is a 3-wire control


3. Next, let's analyze the sound card system of the Linux kernel


There are two sound card systems in Linux sound card, one is OSS (Open Sound System) and the other is ALSA (Advanced Linux Sound Architecture). This section takes OSS (Open Sound System) as an example.


The kernel version is linux-2.6.22.6, located at: linux-2.6.22.6soundsound_core.c


3.1 First enter the entry function


As shown below:


In the entry function, only a "sound" character device and class with a major device number of (SOUND_MAJOR) 14 are registered. Why is there no device node created here?


This is because, after registering the driver of the sound card system, there will be a device node. At this time, the code here has no driver, which will be analyzed later.


3.2 Let's look at the file_operations of the "sound" character device:


There is only one .open here, why is there no read, write function?


Obviously, some processing is done in the .open function. Let's go into soundcore_open() and take a look.


The code for soundcore_open() is as follows:


int soundcore_open(struct inode *inode, struct file *file)

{

int chain;

int unit = iminor(inode); //Get the secondary device number and find the sound card driver through the secondary device number

struct sound_unit *s;

const struct file_operations *new_fops = NULL; //define a new file_operations

 

chain=unit&0x0F;

if(chain==4 || chain==5) /* dsp/audio/dsp16 */

{

unit&=0xF0;

unit|=3;

chain=3;

}

spin_lock(&sound_loader_lock);

s = __look_for_unit(chain, unit); //Find the sound_unit structure in the chains[chain] array. One sound_unit corresponds to one sound card driver.

if (s)

new_fops = fops_get(s->unit_fops); //Get the corresponding file_operations through sound_unit

... ...

if (new_fops) {//When file_operations is found

int err = 0;

const struct file_operations *old_fops = file->f_op; //Set the last file_operations to the current one

file->f_op = new_fops; //Set the system's file_operations to be equal to s->unit_fops

spin_unlock(&sound_loader_lock);

if(file->f_op->open)

err = file->f_op->open(inode,file);

if (err) {

fops_put(file->f_op);

file->f_op = fops_get(old_fops);

}

fops_put(old_fops);

return err;

}

spin_unlock(&sound_loader_lock);

return -ENODEV;

}


Through the above code and comments, we can analyze that the reason why the system sound card has only one open() is that it calls the __look_for_unit() function through the secondary device number, finds the driver sound card sound_unit structure in the chains[chain] array, and then replaces the file_operations of the system sound card to achieve the effect of stealing the sky and replacing the day.


The __look_for_unit() function is shown in the figure below:


static struct sound_unit *__look_for_unit(int chain, int unit)

{

struct sound_unit *s;

s=chains[chain];

while(s && s->unit_minor <= unit)

{

if(s->unit_minor==unit)

return s;

s=s->next;

}

return NULL;

}

The chains[] array is defined as follows:


Among them, the Mixers stored in chains[0] are used to adjust the volume, treble, etc., which is the control interface of our VM8976


The DSP stored in chains[3] is used to implement audio input and output, which is the I2S interface of our VM8976.


Obviously, VM8976 has two drivers. We need to put two file_operations into chains[0] and chains[3] arrays to provide the system with open() to call.


3.3 Let’s take DSP as an example and search for chains[3] to see


As shown in the figure above, it is obvious that the register_sound_dsp() function is called by our sound card driver to register the dsp device node. Let's continue to enter the sound_insert_unit() function to see


3.4 sound_insert_unit() function is as follows


static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev)

{

struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); // allocate a new sound_unit

int r;

 

if (!s)

return -ENOMEM;

spin_lock(&sound_loader_lock);

 

//The main implementation in __sound_insert_unit() is: insert the allocated new s into chains[3], and then put it into the fops operation structure

 

r = __sound_insert_unit(s, list, fops, index, low, top);

spin_unlock(&sound_loader_lock);

if (r < 0)

goto fail;

else if (r < SOUND_STEP)

sprintf(s->name, "sound/%s", name);

else

sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);

 

device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),

      s->name+6);

    //s->name+6="dsp", that is, create a device node of "dsp" under /dev

 

return r;

 

 fail:

kfree(s);

return r;

}

Therefore, the register_sound_dsp() function is used to create the /dev/dsp device node and put the dsp-related file_operations into chains[3].


3.5 Similarly, the driving process of Mixers is the same. Its function is register_sound_mixer(), as shown in the following figure:


It also creates the /dev/mixer device node and puts the dsp-related file_operations into chains[0]


3.6 Next, we search for the register_sound_dsp() function to see which sound card drivers call it.


The uda1341 sound card is very similar to the WM8976 sound card. The audio is an I2S interface, only the control part is different.

[1] [2] [3]
Keywords:S3C2440 Reference address:S3C2440 sound card driver transplantation, testing and madplay playback of mp3 files (31)

Previous article:S3C2440 hot-swap driver modifies mdev configuration to support automatic mounting of USB disk (33)
Next article:S3C2440 RTC real-time clock driver analysis and use (30)

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号