Ok, I found the problem.
On PC, we don't need to call snd_pcm_sw_params_set_avail_min, it works great. However, on our arm machine, we have to set it, otherwise, the status of the buffer is unpredictable, which caused choppy sound and background noise. And when you check the status of the playback device, u won't see the underruns, everything is works great except the avail and avail_max values.
Hope this will help someone else. :)