blob: b7d1fe8e7d82211728d677d440e2780af4c9f980 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "a113-pdm.h"
#include <ddk/debug.h>
#include <unistd.h>
// Filter configuration
static const int lpf1[] = {
0x000014, 0xffffb2, 0xfffed9, 0xfffdce, 0xfffd45, 0xfffe32, 0x000147,
0x000645, 0x000b86, 0x000e21, 0x000ae3, 0x000000, 0xffeece, 0xffdca8,
0xffd212, 0xffd7d1, 0xfff2a7, 0x001f4c, 0x0050c2, 0x0072aa, 0x006ff1,
0x003c32, 0xffdc4e, 0xff6a18, 0xff0fef, 0xfefbaf, 0xff4c40, 0x000000,
0x00ebc8, 0x01c077, 0x02209e, 0x01c1a4, 0x008e60, 0xfebe52, 0xfcd690,
0xfb8fa5, 0xfba498, 0xfd9812, 0x0181ce, 0x06f5f3, 0x0d112f, 0x12a958,
0x169686, 0x18000e, 0x169686, 0x12a958, 0x0d112f, 0x06f5f3, 0x0181ce,
0xfd9812, 0xfba498, 0xfb8fa5, 0xfcd690, 0xfebe52, 0x008e60, 0x01c1a4,
0x02209e, 0x01c077, 0x00ebc8, 0x000000, 0xff4c40, 0xfefbaf, 0xff0fef,
0xff6a18, 0xffdc4e, 0x003c32, 0x006ff1, 0x0072aa, 0x0050c2, 0x001f4c,
0xfff2a7, 0xffd7d1, 0xffd212, 0xffdca8, 0xffeece, 0x000000, 0x000ae3,
0x000e21, 0x000b86, 0x000645, 0x000147, 0xfffe32, 0xfffd45, 0xfffdce,
0xfffed9, 0xffffb2, 0x000014,
};
static const int lpf3[] = {
0x000000, 0x000081, 0x000000, 0xfffedb, 0x000000, 0x00022d, 0x000000,
0xfffc46, 0x000000, 0x0005f7, 0x000000, 0xfff6eb, 0x000000, 0x000d4e,
0x000000, 0xffed1e, 0x000000, 0x001a1c, 0x000000, 0xffdcb0, 0x000000,
0x002ede, 0x000000, 0xffc2d1, 0x000000, 0x004ebe, 0x000000, 0xff9beb,
0x000000, 0x007dd7, 0x000000, 0xff633a, 0x000000, 0x00c1d2, 0x000000,
0xff11d5, 0x000000, 0x012368, 0x000000, 0xfe9c45, 0x000000, 0x01b252,
0x000000, 0xfdebf6, 0x000000, 0x0290b8, 0x000000, 0xfcca0d, 0x000000,
0x041d7c, 0x000000, 0xfa8152, 0x000000, 0x07e9c6, 0x000000, 0xf28fb5,
0x000000, 0x28b216, 0x3fffde, 0x28b216, 0x000000, 0xf28fb5, 0x000000,
0x07e9c6, 0x000000, 0xfa8152, 0x000000, 0x041d7c, 0x000000, 0xfcca0d,
0x000000, 0x0290b8, 0x000000, 0xfdebf6, 0x000000, 0x01b252, 0x000000,
0xfe9c45, 0x000000, 0x012368, 0x000000, 0xff11d5, 0x000000, 0x00c1d2,
0x000000, 0xff633a, 0x000000, 0x007dd7, 0x000000, 0xff9beb, 0x000000,
0x004ebe, 0x000000, 0xffc2d1, 0x000000, 0x002ede, 0x000000, 0xffdcb0,
0x000000, 0x001a1c, 0x000000, 0xffed1e, 0x000000, 0x000d4e, 0x000000,
0xfff6eb, 0x000000, 0x0005f7, 0x000000, 0xfffc46, 0x000000, 0x00022d,
0x000000, 0xfffedb, 0x000000, 0x000081, 0x000000,
};
static const int lpf2[] = {
0x00050a, 0xfff004, 0x0002c1, 0x003c12, 0xffa818, 0xffc87d, 0x010aef,
0xff5223, 0xfebd93, 0x028f41, 0xff5c0e, 0xfc63f8, 0x055f81, 0x000000,
0xf478a0, 0x11c5e3, 0x2ea74d, 0x11c5e3, 0xf478a0, 0x000000, 0x055f81,
0xfc63f8, 0xff5c0e, 0x028f41, 0xfebd93, 0xff5223, 0x010aef, 0xffc87d,
0xffa818, 0x003c12, 0x0002c1, 0xfff004, 0x00050a,
};
void a113_pdm_enable(a113_audio_device_t* audio_device, int is_enable) {
if (is_enable) {
a113_pdm_update_bits(audio_device, PDM_CTRL, 1 << 31, is_enable << 31);
} else {
a113_pdm_update_bits(audio_device, PDM_CTRL, 1 << 31 | 1 << 16,
0 << 31 | 0 << 16);
// Amlogic recommend a sleep after pdm_disable. Not sure why yet. In
// our code structure the sleep doesn't actually do anything since all
// the code is async. Disable it for now, and revisit if we actually
// end up seeing issues here.
// zx_nanosleep(1);
}
}
void a113_pdm_fifo_reset(a113_audio_device_t* audio_device) {
// Toggle this bit for fifo reset.
a113_pdm_update_bits(audio_device, PDM_CTRL, 1 << 16, 0 << 16);
a113_pdm_update_bits(audio_device, PDM_CTRL, 1 << 16, 1 << 16);
}
void a113_pdm_ctrl(a113_audio_device_t* audio_device, int bitdepth) {
a113_pdm_write(audio_device, PDM_CLKG_CTRL, 1);
uint32_t mode = bitdepth == 32 ? 0 : 1;
a113_pdm_update_bits(
audio_device, PDM_CTRL, (0x7 << 28 | 0xff << 8 | 0xff << 0),
(0 << 30) | (mode << 29) | (0 << 28) | (0xff << 8) | (0xff << 0));
a113_pdm_write(audio_device, PDM_CHAN_CTRL,
((28 << 24) | (28 << 16) | (28 << 8) | (28 << 0)));
a113_pdm_write(audio_device, PDM_CHAN_CTRL1,
((28 << 24) | (28 << 16) | (28 << 8) | (28 << 0)));
}
void a113_pdm_arb_config(a113_audio_device_t* aml_tdm_dev) {
a113_ee_audio_write(aml_tdm_dev, EE_AUDIO_ARB_CTRL, 1 << 31 | 0xff << 0);
}
static void a113_pdm_filters_config(a113_audio_device_t* audio_device,
int lpf1_len, int lpf2_len, int lpf3_len) {}
static void a113_pdm_LPF_coeff(a113_audio_device_t* audio_device, int lpf1_len,
const int* lpf1_coeff, int lpf2_len,
const int* lpf2_coeff, int lpf3_len,
const int* lpf3_coeff) {}
void a113_pdm_filter_ctrl(a113_audio_device_t* audio_device) {
a113_pdm_write(
audio_device, PDM_HCIC_CTRL1,
(0x80000000 | 0x7 | (0x8 << 4) | (0x80 << 16) | (0x11 << 24)));
a113_pdm_write(audio_device, PDM_F1_CTRL,
(0x80000000 | 87 | (2 << 12) | (1 << 16)));
a113_pdm_write(audio_device, PDM_F2_CTRL,
(0x80000000 | 33 | (2 << 12) | (0 << 16)));
a113_pdm_write(audio_device, PDM_F3_CTRL,
(0x80000000 | 117 | (2 << 12) | (1 << 16)));
a113_pdm_write(audio_device, PDM_HPF_CTRL,
(0x8000 | (0x7 << 16) | (1 << 31)));
a113_pdm_write(audio_device, PDM_COEFF_ADDR, 0);
for (int i = 0; i < 87; i++)
a113_pdm_write(audio_device, PDM_COEFF_DATA, lpf1[i]);
for (int i = 0; i < 33; i++)
a113_pdm_write(audio_device, PDM_COEFF_DATA, lpf2[i]);
for (int i = 0; i < 117; i++)
a113_pdm_write(audio_device, PDM_COEFF_DATA, lpf3[i]);
a113_pdm_write(audio_device, PDM_COEFF_ADDR, 0);
}