atv_demod: Add atv demod

PD#163853: Add atv demod

Change-Id: I572568d30136801cfb244757a5d1114974158192
Signed-off-by: nengwen.chen <nengwen.chen@amlogic.com>
This commit is contained in:
nengwen.chen
2018-04-12 11:11:22 +08:00
committed by Yixun Lan
parent e7b8b75b3e
commit cadc6e9ee2
28 changed files with 10379 additions and 32 deletions

View File

@@ -14409,3 +14409,7 @@ AMLOGIC ADD LCD_EXTERN TL050FHV02CT DRIVER
M: Weiming Liu <weiming.liu@amlogic.com>
F: drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c
AMLOGIC ATV DEMOD DRIVER
M: nengwen.chen <nengwen.chen@amlogic.com>
F: drivers/amlogic/atv_demod/*
F: include/linux/amlogic/aml_atvdemod.h

View File

@@ -590,16 +590,20 @@
interrupt-names = "mailbox_2";
};
aml_atv_demod {
compatible = "amlogic, aml_atv_demod";
dev_name = "aml_atv_demod";
status = "disabled";
aml_atvdemod {
compatible = "amlogic, aml_atvdemod";
dev_name = "aml_atvdemod";
status = "okay";
tuner = "si2151_tuner";
tuner_i2c_ada_id = <&i2c1>;
tuner_i2c_addr = <0x60>;
btsc_sap_mode = <1>;
////pinctrl-names="atvdemod_agc";
////pinctrl-0=<&atvdemod_agc>;
reg = <0x0 0xff640000 0x0 0x2000
0x0 0xff648000 0x0 0x2000>;
/* default:0x88188832;r840 on haier:0x48188832 */
0x0 0xff648000 0x0 0x2000>;
reg_23cf = <0x88188832>;
/*default:0x88188832;r840 on haier:0x48188832*/
};
bt-dev {

View File

@@ -583,16 +583,20 @@
interrupt-names = "mailbox_2";
};
aml_atv_demod {
compatible = "amlogic, aml_atv_demod";
dev_name = "aml_atv_demod";
status = "disabled";
aml_atvdemod {
compatible = "amlogic, aml_atvdemod";
dev_name = "aml_atvdemod";
status = "okay";
tuner = "mxl661_tuner";
tuner_i2c_ada_id = <&i2c1>;
tuner_i2c_addr = <0x60>;
btsc_sap_mode = <1>;
////pinctrl-names="atvdemod_agc";
////pinctrl-0=<&atvdemod_agc>;
reg = <0x0 0xff640000 0x0 0x2000
0x0 0xff648000 0x0 0x2000>;
/* default:0x88188832;r840 on haier:0x48188832 */
0x0 0xff648000 0x0 0x2000>;
reg_23cf = <0x88188832>;
/*default:0x88188832;r840 on haier:0x48188832*/
};
bt-dev {
@@ -1380,6 +1384,13 @@
};
};
&i2c1 {
status = "okay";
clock-frequency = <300000>;
pinctrl-names="default";
pinctrl-0=<&i2c1_dv_pins>;
};
&pinctrl_periphs {
/*i2s*/
aml_audio_i2s: aml_audio_i2s {

View File

@@ -592,16 +592,20 @@
interrupt-names = "mailbox_2";
};
aml_atv_demod {
compatible = "amlogic, aml_atv_demod";
dev_name = "aml_atv_demod";
status = "disabled";
aml_atvdemod {
compatible = "amlogic, aml_atvdemod";
dev_name = "aml_atvdemod";
status = "okay";
tuner = "mxl661_tuner";
tuner_i2c_ada_id = <&i2c1>;
tuner_i2c_addr = <0x60>;
btsc_sap_mode = <1>;
////pinctrl-names="atvdemod_agc";
////pinctrl-0=<&atvdemod_agc>;
reg = <0x0 0xff640000 0x0 0x2000
0x0 0xff648000 0x0 0x2000>;
/* default:0x88188832;r840 on haier:0x48188832 */
0x0 0xff648000 0x0 0x2000>;
reg_23cf = <0x88188832>;
/*default:0x88188832;r840 on haier:0x48188832*/
};
bt-dev {
@@ -1389,6 +1393,13 @@
};
};
&i2c1 {
status = "okay";
clock-frequency = <300000>;
pinctrl-names="default";
pinctrl-0=<&i2c1_dv_pins>;
};
&pinctrl_periphs {
/*i2s*/
aml_audio_i2s: aml_audio_i2s {

View File

@@ -591,16 +591,20 @@
interrupt-names = "mailbox_2";
};
aml_atv_demod {
compatible = "amlogic, aml_atv_demod";
dev_name = "aml_atv_demod";
status = "disabled";
aml_atvdemod {
compatible = "amlogic, aml_atvdemod";
dev_name = "aml_atvdemod";
status = "okay";
tuner = "mxl661_tuner";
tuner_i2c_ada_id = <&i2c1>;
tuner_i2c_addr = <0x60>;
btsc_sap_mode = <1>;
////pinctrl-names="atvdemod_agc";
////pinctrl-0=<&atvdemod_agc>;
reg = <0x0 0xff640000 0x0 0x2000
0x0 0xff648000 0x0 0x2000>;
/* default:0x88188832;r840 on haier:0x48188832 */
0x0 0xff648000 0x0 0x2000>;
reg_23cf = <0x88188832>;
/*default:0x88188832;r840 on haier:0x48188832*/
};
bt-dev {
@@ -1388,6 +1392,13 @@
};
};
&i2c1 {
status = "okay";
clock-frequency = <300000>;
pinctrl-names="default";
pinctrl-0=<&i2c1_dv_pins>;
};
&pinctrl_periphs {
/*i2s*/
aml_audio_i2s: aml_audio_i2s {

View File

@@ -346,6 +346,7 @@ CONFIG_AMLOGIC_DDR_TOOL=y
CONFIG_AMLOGIC_DDR_BANDWIDTH=y
CONFIG_AMLOGIC_TEE=y
CONFIG_AMLOGIC_GPIO_IRQ=y
CONFIG_AMLOGIC_ATV_DEMOD=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y

View File

@@ -125,5 +125,8 @@ source "drivers/amlogic/ledring/Kconfig"
source "drivers/amlogic/memory_ext/Kconfig"
source "drivers/amlogic/irqchip/Kconfig"
source "drivers/amlogic/atv_demod/Kconfig"
endmenu
endif

View File

@@ -116,3 +116,5 @@ obj-$(CONFIG_AMLOGIC_MEMORY_EXTEND) += memory_ext/
obj-$(CONFIG_AMLOGIC_LEDRING) += ledring/
obj-$(CONFIG_AMLOGIC_GPIO_IRQ) += irqchip/
obj-$(CONFIG_AMLOGIC_ATV_DEMOD) += atv_demod/

View File

@@ -0,0 +1,17 @@
#
# ATV driver configuration
#
menu "Amlogic ATV driver"
config AMLOGIC_ATV_DEMOD
tristate "Amlogic ATVDEMOD device driver"
default n
help
ATVDEMOD device driver.
Y: enable
N: disable
M: build as module
endmenu

View File

@@ -0,0 +1,32 @@
obj-$(CONFIG_AMLOGIC_ATV_DEMOD) += aml_atvdemod.o
aml_atvdemod-objs = atvdemod_func.o atvauddemod_func.o atv_demod_v4l2.o atv_demod_driver.o atv_demod_ops.o
ccflags-y += -I.
ccflags-y += -Idrivers/media/dvb-core
#ccflags-y += -Idrivers/amlogic/tuners/mxl661
#ccflags-y += -Idrivers/amlogic/tuners/si2151
#obj-m += aml_atvdemod.o
#
#aml_atvdemod-objs = atvdemod_func.o atvauddemod_func.o
#
#aml_atvdemod-objs += atv_demod_v4l2.o atv_demod_driver.o atv_demod_ops.o
#
#ccflags-y += -I.
#ccflags-y += -Idrivers/media/dvb-core
#
#TARGET_PRODUCT=t962e_r321
#KERNEL_ARCH=arm64
#CROSS_COMPILE=aarch64-linux-gnu-
#PRODUCT_OUT=../../../../out/target/product/$(TARGET_PRODUCT)/obj/KERNEL_OBJ
#
#KBUILD_EXTRA_SYMBOLS += $(shell pwd)/../tuner/si2151_4.9/Module.symvers
#
#export KBUILD_EXTRA_SYMBOLS
#
#all:
# $(MAKE) -C $(PRODUCT_OUT) M=$(shell pwd) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
#
#clean:
# rm -rf *.ko .*.ko.cmd *.o *.order *.symvers -f *.cmd .*.o.cmd *.mod.c .tmp_versions/

View File

@@ -0,0 +1,40 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ATV_DEMOD_DEBUG_H__
#define __ATV_DEMOD_DEBUG_H__
extern int atvdemod_debug_en;
#undef pr_info
#define pr_info(args...)\
do {\
if (atvdemod_debug_en)\
printk(args);\
} while (0)
#undef pr_dbg
#define pr_dbg(args...) \
do {\
if (atvdemod_debug_en == 2)\
printk(args);\
} while (0)
#undef pr_err
#define pr_err(args...) \
do {\
if (1)\
printk(args);\
} while (0)
#endif /* __ATV_DEMOD_DEBUG_H__ */

View File

@@ -0,0 +1,598 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#define ATVDEMOD_DEVICE_NAME "aml_atvdemod"
#define ATVDEMOD_DRIVER_NAME "aml_atvdemod"
#define ATVDEMOD_MODULE_NAME "aml_atvdemod"
#define ATVDEMOD_CLASS_NAME "aml_atvdemod"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/amlogic/cpu_version.h>
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include "drivers/media/dvb-core/dvb_frontend.h"
#include "atv_demod_debug.h"
#include "atv_demod_driver.h"
#include "atv_demod_v4l2.h"
#include "atv_demod_ops.h"
#include "atvdemod_func.h"
#include "atvauddemod_func.h"
#define AMLATVDEMOD_VER "Ref.2015/09/01a"
struct aml_atvdemod_device *amlatvdemod_devp;
static ssize_t aml_atvdemod_store(struct class *class,
struct class_attribute *attr, const char *buf, size_t count)
{
int n = 0;
unsigned int ret = 0;
char *buf_orig = NULL, *ps = NULL, *token = NULL;
char *parm[4] = { NULL };
unsigned int data_snr[128] = { 0 };
unsigned int data_snr_avg = 0;
int data_afc = 0, block_addr = 0, block_reg = 0, block_val = 0;
int i = 0, val = 0;
unsigned long tmp = 0;
struct aml_atvdemod_device *aml_atvdemod_dev = NULL;
aml_atvdemod_dev = container_of(class, struct aml_atvdemod_device, cls);
buf_orig = kstrdup(buf, GFP_KERNEL);
ps = buf_orig;
while (1) {
token = strsep(&ps, "\n ");
if (token == NULL)
break;
if (*token == '\0')
continue;
parm[n++] = token;
}
if (!strncmp(parm[0], "init", strlen("init"))) {
ret = atv_demod_enter_mode();
if (ret)
pr_info("[tuner..] atv_restart error.\n");
} else if (!strncmp(parm[0], "audout_mode", strlen("audout_mode"))) {
if (get_atvdemod_state() == ATVDEMOD_STATE_WORK) {
if (is_meson_txlx_cpu()) {
atvauddemod_set_outputmode();
pr_info("[tuner..] atvauddemod_set_outputmode done ....\n");
}
} else {
pr_info("[tuner..] atvdemod_state not work ....\n");
}
} else if (!strncmp(parm[0], "signal_audmode",
strlen("signal_audmode"))) {
int stereo_flag, sap_flag;
if (get_atvdemod_state() == ATVDEMOD_STATE_WORK) {
if (is_meson_txlx_cpu()) {
update_btsc_mode(1, &stereo_flag, &sap_flag);
pr_info("[tuner..] get signal_audmode done ....\n");
}
} else {
pr_info("[tuner..] atvdemod_state not work ....\n");
}
} else if (!strncmp(parm[0], "clk", 3)) {
adc_set_pll_cntl(1, 0x1, NULL);
atvdemod_clk_init();
if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
aud_demod_clk_gate(1);
pr_info("atvdemod_clk_init done ....\n");
} else if (!strcmp(parm[0], "tune")) {
/* val = simple_strtol(parm[1], NULL, 10); */
} else if (!strcmp(parm[0], "set")) {
if (!strncmp(parm[1], "avout_gain", strlen("avout_gain"))) {
if (kstrtoul(buf + strlen("avout_offset") + 1,
10, &tmp) == 0)
val = tmp;
atv_dmd_wr_byte(0x0c, 0x01, val & 0xff);
} else if (!strncmp(parm[1], "avout_offset",
strlen("avout_offset"))) {
if (kstrtoul(buf + strlen("avout_offset") + 1,
10, &tmp) == 0)
val = tmp;
atv_dmd_wr_byte(0x0c, 0x04, val & 0xff);
} else if (!strncmp(parm[1], "atv_gain",
strlen("atv_gain"))) {
if (kstrtoul(buf + strlen("atv_gain") + 1,
10, &tmp) == 0)
val = tmp;
atv_dmd_wr_byte(0x19, 0x01, val & 0xff);
} else if (!strncmp(parm[1], "atv_offset",
strlen("atv_offset"))) {
if (kstrtoul(buf + strlen("atv_offset") + 1,
10, &tmp) == 0)
val = tmp;
atv_dmd_wr_byte(0x19, 0x04, val & 0xff);
}
} else if (!strcmp(parm[0], "get")) {
if (!strncmp(parm[1], "avout_gain", strlen("avout_gain"))) {
val = atv_dmd_rd_byte(0x0c, 0x01);
pr_dbg("avout_gain:0x%x\n", val);
} else if (!strncmp(parm[1], "avout_offset",
strlen("avout_offset"))) {
val = atv_dmd_rd_byte(0x0c, 0x04);
pr_dbg("avout_offset:0x%x\n", val);
} else if (!strncmp(parm[1], "atv_gain",
strlen("atv_gain"))) {
val = atv_dmd_rd_byte(0x19, 0x01);
pr_dbg("atv_gain:0x%x\n", val);
} else if (!strncmp(parm[1], "atv_offset",
strlen("atv_offset"))) {
val = atv_dmd_rd_byte(0x19, 0x04);
pr_dbg("atv_offset:0x%x\n", val);
}
} else if (!strncmp(parm[0], "snr_hist", strlen("snr_hist"))) {
data_snr_avg = 0;
for (i = 0; i < 128; i++) {
data_snr[i] = (atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC,
0x50) >> 8);
usleep_range(50 * 1000, 50 * 1000 + 100);
data_snr_avg += data_snr[i];
}
data_snr_avg = data_snr_avg / 128;
pr_dbg("**********snr_hist_128avg:0x%x(%d)*********\n",
data_snr_avg,
data_snr_avg);
} else if (!strncmp(parm[0], "afc_info", strlen("afc_info"))) {
data_afc = retrieve_vpll_carrier_afc();
pr_dbg("[amlatvdemod..]afc %d Khz.\n", data_afc);
} else if (!strncmp(parm[0], "ver_info", strlen("ver_info"))) {
pr_dbg("[amlatvdemod..]aml_atvdemod_ver %s.\n",
AMLATVDEMOD_VER);
} else if (!strncmp(parm[0], "audio_autodet",
strlen("audio_autodet"))) {
aml_audiomode_autodet(NULL);
} else if (!strncmp(parm[0], "overmodule_det",
strlen("overmodule_det"))) {
/* unsigned long over_threshold, */
/* int det_mode = auto_det_mode; */
aml_atvdemod_overmodule_det();
} else if (!strncmp(parm[0], "audio_gain_set",
strlen("audio_gain_set"))) {
if (kstrtoul(buf + strlen("audio_gain_set") + 1, 16, &tmp) == 0)
val = tmp;
aml_audio_valume_gain_set(val);
pr_dbg("audio_gain_set : %d\n", val);
} else if (!strncmp(parm[0], "audio_gain_get",
strlen("audio_gain_get"))) {
val = aml_audio_valume_gain_get();
pr_dbg("audio_gain_get : %d\n", val);
} else if (!strncmp(parm[0], "fix_pwm_adj",
strlen("fix_pwm_adj"))) {
if (kstrtoul(parm[1], 10, &tmp) == 0) {
val = tmp;
aml_fix_PWM_adjust(val);
}
} else if (!strncmp(parm[0], "rs", strlen("rs"))) {
if (kstrtoul(parm[1], 16, &tmp) == 0)
block_addr = tmp;
if (kstrtoul(parm[2], 16, &tmp) == 0)
block_reg = tmp;
if (block_addr < APB_BLOCK_ADDR_TOP)
block_val = atv_dmd_rd_long(block_addr, block_reg);
pr_dbg("rs block_addr:0x%x,block_reg:0x%x,block_val:0x%x\n",
block_addr,
block_reg, block_val);
} else if (!strncmp(parm[0], "ws", strlen("ws"))) {
if (kstrtoul(parm[1], 16, &tmp) == 0)
block_addr = tmp;
if (kstrtoul(parm[2], 16, &tmp) == 0)
block_reg = tmp;
if (kstrtoul(parm[3], 16, &tmp) == 0)
block_val = tmp;
if (block_addr < APB_BLOCK_ADDR_TOP)
atv_dmd_wr_long(block_addr, block_reg, block_val);
pr_dbg("ws block_addr:0x%x,block_reg:0x%x,block_val:0x%x\n",
block_addr,
block_reg, block_val);
block_val = atv_dmd_rd_long(block_addr, block_reg);
pr_dbg("readback_val:0x%x\n", block_val);
} else if (!strncmp(parm[0], "pin_mux", strlen("pin_mux"))) {
aml_atvdemod_dev->pin = devm_pinctrl_get_select(
aml_atvdemod_dev->dev,
aml_atvdemod_dev->pin_name);
pr_dbg("atvdemod agc pinmux name:%s\n",
aml_atvdemod_dev->pin_name);
} else if (!strncmp(parm[0], "snr_cur", strlen("snr_cur"))) {
data_snr_avg = aml_atvdemod_get_snr_ex();
pr_dbg("**********snr_cur:%d*********\n", data_snr_avg);
} else if (!strncmp(parm[0], "pll_status", strlen("pll_status"))) {
int vpll_lock;
retrieve_vpll_carrier_lock(&vpll_lock);
if ((vpll_lock & 0x1) == 0)
pr_dbg("visual carrier lock:locked\n");
else
pr_dbg("visual carrier lock:unlocked\n");
} else if (!strncmp(parm[0], "line_lock", strlen("line_lock"))) {
int line_lock;
retrieve_vpll_carrier_line_lock(&line_lock);
if (line_lock == 0)
pr_dbg("line lock:locked\n");
else
pr_dbg("line lock:unlocked\n");
} else if (!strncmp(parm[0], "audio_power", strlen("audio_power"))) {
int audio_power = 0;
retrieve_vpll_carrier_audio_power(&audio_power);
} else if (!strncmp(parm[0], "adc_power", strlen("adc_power"))) {
int adc_power = 0;
retrieve_adc_power(&adc_power);
pr_dbg("adc_power:%d\n", adc_power);
} else if (!strncmp(parm[0], "search_atv", strlen("search_atv"))) {
unsigned int freq = 0;
struct analog_parameters params;
struct dvb_frontend *fe = NULL;
fe = &aml_atvdemod_dev->v4l2_fe.v4l2_ad->fe;
if (kstrtoul(parm[1], 10, &tmp) == 0)
freq = tmp;
params.frequency = freq;
params.mode = 1;
params.audmode = 0;
params.std = V4L2_STD_PAL_I;
fe->ops.analog_ops.set_params(fe, &params);
} else if (!strncmp(parm[0], "mode_set", strlen("mode_set"))) {
int priv_cfg = AML_ATVDEMOD_INIT;
struct dvb_frontend *fe = NULL;
fe = &aml_atvdemod_dev->v4l2_fe.v4l2_ad->fe;
if (kstrtoul(parm[1], 10, &tmp) == 0)
priv_cfg = tmp;
fe->ops.analog_ops.set_config(fe, &priv_cfg);
} else
pr_dbg("invalid command\n");
kfree(buf_orig);
return count;
}
static ssize_t aml_atvdemod_show(struct class *cls,
struct class_attribute *attr, char *buff)
{
pr_dbg("\n usage:\n");
pr_dbg("[get soft version] echo ver_info > /sys/class/amlatvdemod/atvdemod_debug\n");
pr_dbg("[get afc value] echo afc_info > /sys/class/amlatvdemod/atvdemod_debug\n");
pr_dbg("[reinit atvdemod] echo init > /sys/class/amlatvdemod/atvdemod_debug\n");
pr_dbg("[get av-out-gain/av-out-offset/atv-gain/atv-offset]:\n"
"echo get av_gain/av_offset/atv_gain/atv_offset > /sys/class/amlatvdemod/atvdemod_debug\n");
pr_dbg("[set av-out-gain/av-out-offset/atv-gain/atv-offset]:\n"
"echo set av_gain/av_offset/atv_gain/atv_offset val(0~255) > /sys/class/amlatvdemod/atvdemod_debug\n");
return 0;
}
static struct class_attribute atvdemod_debug_class_attrs[] = {
__ATTR(atvdemod_debug, 0644, aml_atvdemod_show, aml_atvdemod_store),
__ATTR_NULL
};
static void aml_atvdemod_dt_parse(struct aml_atvdemod_device *pdev)
{
struct device_node *node = NULL;
struct device_node *node_i2c = NULL;
unsigned int val = 0;
const char *str = NULL;
int ret = 0;
node = pdev->dev->of_node;
if (node) {
ret = of_property_read_u32(node, "reg_23cf", &val);
if (ret)
pr_err("can't find reg_23cf.\n");
else
pdev->reg_23cf = val;
ret = of_property_read_u32(node, "audio_gain_val", &val);
if (ret)
pr_err("can't find audio_gain_val.\n");
else
set_audio_gain_val(val);
ret = of_property_read_u32(node, "video_gain_val", &val);
if (ret)
pr_err("can't find video_gain_val.\n");
else
set_video_gain_val(val);
/* agc pin mux */
ret = of_property_read_string(node, "pinctrl-names",
&pdev->pin_name);
if (!ret) {
#if 0
amlatvdemod_devp->pin = devm_pinctrl_get_select(
&pdev->dev, pdev->pin_name);
#endif
pr_err("atvdemod agc pinmux name: %s\n",
pdev->pin_name);
}
ret = of_property_read_u32(node, "btsc_sap_mode", &val);
if (ret)
pr_err("can't find btsc_sap_mode.\n");
else
pdev->btsc_sap_mode = val;
ret = of_property_read_string(node, "tuner", &str);
if (ret)
pr_err("can't find tuner.\n");
else {
if (!strncmp(str, "mxl661_tuner",
strlen("mxl661_tuner")))
pdev->tuner_id = AM_TUNER_MXL661;
else if (!strncmp(str, "si2151_tuner",
strlen("si2151_tuner")))
pdev->tuner_id = AM_TUNER_SI2151;
else if (!strncmp(str, "r840_tuner",
strlen("r840_tuner")))
pdev->tuner_id = AM_TUNER_R840;
else
pr_err("can't find tuner: %s.\n", str);
}
node_i2c = of_parse_phandle(node, "tuner_i2c_ada_id", 0);
if (node_i2c) {
pdev->i2c_adp = of_find_i2c_adapter_by_node(node_i2c);
of_node_put(node_i2c);
if (!pdev->i2c_adp)
pr_err("can't find tuner_i2c_adap.\n");
}
#if 0
ret = of_property_read_u32(node, "tuner_i2c_ada_id", &val);
if (ret)
pr_err("can't find tuner_i2c_ada_id.\n");
else
pdev->i2c_adapter_id = val;
#endif
ret = of_property_read_u32(node, "tuner_i2c_addr", &val);
if (ret)
pr_err("can't find tuner_i2c_addr.\n");
else
pdev->i2c_addr = val;
}
}
static int aml_atvdemod_probe(struct platform_device *pdev)
{
int ret = 0;
struct resource *res = NULL;
int size_io_reg = 0;
struct aml_atvdemod_device *dev = NULL;
pr_info("%s.\n", __func__);
dev = kzalloc(sizeof(struct aml_atvdemod_device), GFP_KERNEL);
if (!dev) {
ret = -ENOMEM;
goto fail_alloc_device;
}
dev->name = ATVDEMOD_DEVICE_NAME;
dev->cls.name = kzalloc(strlen(ATVDEMOD_DEVICE_NAME), GFP_KERNEL);
if (!dev->cls.name) {
ret = -ENOMEM;
goto fail_alloc_class;
}
sprintf((char *)dev->cls.name, "%s", ATVDEMOD_DEVICE_NAME);
dev->cls.class_attrs = atvdemod_debug_class_attrs;
ret = class_register(&dev->cls);
if (ret) {
dev_err(&pdev->dev, "class_create fail.\n");
goto fail_create_class;
}
dev->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "get demod memory resource fail.\n");
goto fail_get_resource;
}
size_io_reg = resource_size(res);
dev->demod_reg_base = devm_ioremap_nocache(&pdev->dev,
res->start, size_io_reg);
if (!dev->demod_reg_base) {
dev_err(&pdev->dev, "demod ioremap failed.\n");
goto fail_get_resource;
}
pr_info("demod start = 0x%p, size = 0x%x, demod_reg_base = 0x%p.\n",
(void *) res->start, size_io_reg,
dev->demod_reg_base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res) {
dev_err(&pdev->dev, "no audio demod memory resource.\n");
dev->audio_reg_base = NULL;
} else {
size_io_reg = resource_size(res);
dev->audio_reg_base = devm_ioremap_nocache(
&pdev->dev, res->start, size_io_reg);
if (!dev->audio_reg_base) {
dev_err(&pdev->dev, "audio ioremap failed.\n");
goto fail_get_resource;
}
pr_info("audio start = 0x%p, size = 0x%x, audio_reg_base = 0x%p.\n",
(void *) res->start, size_io_reg,
dev->audio_reg_base);
}
if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
dev->hiu_reg_base = ioremap(0xff63c000, 0x2000);
else
dev->hiu_reg_base = ioremap(0xc883c000, 0x2000);
pr_info("hiu_reg_base = 0x%p.\n", dev->hiu_reg_base);
if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
dev->periphs_reg_base = ioremap(0xff634000, 0x2000);
else
dev->periphs_reg_base = ioremap(0xc8834000, 0x2000);
pr_info("periphs_reg_base = 0x%p.\n", dev->periphs_reg_base);
aml_atvdemod_dt_parse(dev);
dev->v4l2_ad.dev = dev->dev;
dev->v4l2_ad.i2c.addr = dev->i2c_addr;
dev->v4l2_ad.i2c.adapter = dev->i2c_adp;
/* i2c_get_adapter(dev->i2c_adapter_id); */
dev->v4l2_ad.tuner_id = dev->tuner_id;
ret = v4l2_resister_frontend(&dev->v4l2_ad, &dev->v4l2_fe);
if (ret) {
dev_err(&pdev->dev, "resister v4l2 fail.\n");
goto fail_register_v4l2;
}
platform_set_drvdata(pdev, dev);
amlatvdemod_devp = dev;
pr_info("probe ok.\n");
return 0;
fail_register_v4l2:
fail_get_resource:
class_unregister(&dev->cls);
fail_create_class:
kfree(dev->cls.name);
fail_alloc_class:
kfree(dev);
fail_alloc_device:
pr_info("[amlatvdemod]: atvdemod_init fail.\n");
return ret;
}
static int aml_atvdemod_remove(struct platform_device *pdev)
{
struct aml_atvdemod_device *dev = platform_get_drvdata(pdev);
if (dev == NULL)
return -1;
class_unregister(&dev->cls);
v4l2_unresister_frontend(&dev->v4l2_fe);
amlatvdemod_devp = NULL;
kfree(dev->cls.name);
kfree(dev);
pr_dbg("[amlatvdemod] : aml_atvdemod_remove.\n");
return 0;
}
static void aml_atvdemod_shutdown(struct platform_device *pdev)
{
pr_info("%s done.\n", __func__);
}
static int aml_atvdemod_suspend(struct platform_device *pdev,
pm_message_t state)
{
struct aml_atvdemod_device *dev = platform_get_drvdata(pdev);
v4l2_frontend_suspend(&dev->v4l2_fe);
pr_info("%s: OK\n", __func__);
return 0;
}
int aml_atvdemod_resume(struct platform_device *pdev)
{
struct aml_atvdemod_device *dev = platform_get_drvdata(pdev);
v4l2_frontend_resume(&dev->v4l2_fe);
pr_info("%s: OK\n", __func__);
return 0;
}
static const struct of_device_id aml_atvdemod_dt_match[] = {
{
.compatible = "amlogic, aml_atvdemod",
},
{
},
};
static struct platform_driver aml_atvdemod_driver = {
.driver = {
.name = "aml_atvdemod",
.owner = THIS_MODULE,
.of_match_table = aml_atvdemod_dt_match,
},
.probe = aml_atvdemod_probe,
.remove = aml_atvdemod_remove,
.shutdown = aml_atvdemod_shutdown,
.suspend = aml_atvdemod_suspend,
.resume = aml_atvdemod_resume,
};
static int __init aml_atvdemod_init(void)
{
if (platform_driver_register(&aml_atvdemod_driver)) {
pr_err("failed to register amlatvdemod driver module\n");
return -ENODEV;
}
pr_dbg("[amlatvdemod..]%s: driver init ok.\n", __func__);
return 0;
}
static void __exit aml_atvdemod_exit(void)
{
platform_driver_unregister(&aml_atvdemod_driver);
pr_dbg("[amlatvdemod..]%s: driver exit ok.\n", __func__);
}
MODULE_AUTHOR("nengwen.chen <nengwen.chen@amlogic.com>");
MODULE_DESCRIPTION("aml atv demod device driver");
MODULE_LICENSE("GPL");
module_init(aml_atvdemod_init);
module_exit(aml_atvdemod_exit);

View File

@@ -0,0 +1,101 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ATV_DEMOD_DRIVER_H__
#define __ATV_DEMOD_DRIVER_H__
extern int atvdemod_debug_en;
#include <media/v4l2-device.h>
#include "drivers/media/dvb-core/dvb_frontend.h"
#include "atv_demod_v4l2.h"
enum aml_tuner_type_t {
AM_TUNER_SI2176 = 1,
AM_TUNER_SI2196 = 2,
AM_TUNER_FQ1216 = 3,
AM_TUNER_HTM = 4,
AM_TUNER_CTC703 = 5,
AM_TUNER_SI2177 = 6,
AM_TUNER_R840 = 7,
AM_TUNER_SI2157 = 8,
AM_TUNER_SI2151 = 9,
AM_TUNER_MXL661 = 10,
AM_TUNER_MXL608 = 11
};
struct aml_atvdemod_parameters {
struct analog_parameters param;
unsigned int soundsys;/* A2,BTSC/EIAJ/NICAM */
unsigned int lock_range;
unsigned int leap_step;
unsigned int afc_range;
unsigned int tuner_id;
unsigned int if_freq;
unsigned int if_inv;
unsigned int reserved;
};
struct aml_atvdemod_device {
char *name;
struct class cls;
struct device *dev;
unsigned int tuner_id;
unsigned int i2c_addr;
unsigned int i2c_adapter_id;
struct i2c_adapter *i2c_adp;
unsigned int if_freq;
unsigned int if_inv;
u64 std;
int fre_offset;
struct pinctrl *pin;
const char *pin_name;
struct v4l2_adapter v4l2_ad;
struct v4l2_frontend v4l2_fe;
void __iomem *demod_reg_base;
void __iomem *audio_reg_base;
void __iomem *hiu_reg_base;
void __iomem *periphs_reg_base;
unsigned int reg_23cf; /* IIR filter */
int btsc_sap_mode; /*0: off 1:monitor 2:auto */
#define ATVDEMOD_STATE_IDEL 0
#define ATVDEMOD_STATE_WORK 1
#define ATVDEMOD_STATE_SLEEP 2
int atvdemod_state;
int (*demod_reg_write)(unsigned int reg, unsigned int val);
int (*demod_reg_read)(unsigned int reg, unsigned int *val);
int (*audio_reg_write)(unsigned int reg, unsigned int val);
int (*audio_reg_read)(unsigned int reg, unsigned int *val);
int (*hiu_reg_write)(unsigned int reg, unsigned int val);
int (*hiu_reg_read)(unsigned int reg, unsigned int *val);
int (*periphs_reg_write)(unsigned int reg, unsigned int val);
int (*periphs_reg_read)(unsigned int reg, unsigned int *val);
};
extern struct aml_atvdemod_device *amlatvdemod_devp;
#endif /* __ATV_DEMOD_DRIVER_H__ */

View File

@@ -0,0 +1,460 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/i2c.h>
#include <uapi/linux/dvb/frontend.h>
#include <linux/amlogic/aml_atvdemod.h>
#include "drivers/media/tuners/tuner-i2c.h"
#include "drivers/media/dvb-core/dvb_frontend.h"
#include "drivers/amlogic/media/vin/tvin/tvafe/tvafe_general.h"
#include "atvdemod_func.h"
#include "atvauddemod_func.h"
#include "atv_demod_debug.h"
#include "atv_demod_driver.h"
#include "atv_demod_ops.h"
#include "atv_demod_v4l2.h"
#define DEVICE_NAME "aml_atvdemod_fe"
#define ATVDEMOD_STATE_IDEL 0
#define ATVDEMOD_STATE_WORK 1
#define ATVDEMOD_STATE_SLEEP 2
static int atvdemod_state = ATVDEMOD_STATE_IDEL;
static DEFINE_MUTEX(atv_demod_list_mutex);
static LIST_HEAD(hybrid_tuner_instance_list);
unsigned int reg_23cf = 0x88188832; /*IIR filter*/
module_param(reg_23cf, uint, 0664);
MODULE_PARM_DESC(reg_23cf, "\n reg_23cf\n");
static int btsc_sap_mode = 1; /*0: off 1:monitor 2:auto */
module_param(btsc_sap_mode, int, 0644);
MODULE_DESCRIPTION("btsc sap mode\n");
/*
* add interface for audio driver to get atv audio state.
* state:
* 0 - no data.
* 1 - has data.
*/
void aml_fe_get_atvaudio_state(int *state)
{
int power = 0;
int vpll_lock = 0;
int line_lock = 0;
if (atvdemod_state == ATVDEMOD_STATE_WORK) {
retrieve_vpll_carrier_lock(&vpll_lock);
retrieve_vpll_carrier_line_lock(&line_lock);
if ((vpll_lock == 0) && (line_lock == 0))
retrieve_vpll_carrier_audio_power(&power);
} else
pr_err("%s, atv is not work, atvdemod_state: %d.\n",
__func__, atvdemod_state);
if (power >= 150)
*state = 1;
else
*state = 0;
pr_info("aml_fe_get_atvaudio_state: %d, power = %d.\n",
*state, power);
}
int aml_atvdemod_get_btsc_sap_mode(void)
{
return btsc_sap_mode;
}
unsigned int atvdemod_scan_mode; /*IIR filter*/
module_param(atvdemod_scan_mode, uint, 0664);
MODULE_PARM_DESC(atvdemod_scan_mode, "\n atvdemod_scan_mode\n");
/* ret:5~100;the val is bigger,the signal is better */
int aml_atvdemod_get_snr(struct dvb_frontend *fe)
{
#if 1
return get_atvdemod_snr_val();
#else
unsigned int snr_val;
int ret;
snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8;
/* snr_val:900000~0xffffff,ret:5~15 */
if (snr_val > 900000)
ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000);
/* snr_val:158000~900000,ret:15~30 */
else if (snr_val > 158000)
ret = 30 - (snr_val - 158000)*15/(900000 - 158000);
/* snr_val:31600~158000,ret:30~50 */
else if (snr_val > 31600)
ret = 50 - (snr_val - 31600)*20/(158000 - 31600);
/* snr_val:316~31600,ret:50~80 */
else if (snr_val > 316)
ret = 80 - (snr_val - 316)*30/(31600 - 316);
/* snr_val:0~316,ret:80~100 */
else
ret = 100 - (316 - snr_val)*20/316;
return ret;
#endif
}
int aml_atvdemod_get_snr_ex(void)
{
#if 1
return get_atvdemod_snr_val();
#else
unsigned int snr_val;
int ret;
snr_val = atv_dmd_rd_long(APB_BLOCK_ADDR_VDAGC, 0x50) >> 8;
/* snr_val:900000~0xffffff,ret:5~15 */
if (snr_val > 900000)
ret = 15 - (snr_val - 900000)*10/(0xffffff - 900000);
/* snr_val:158000~900000,ret:15~30 */
else if (snr_val > 158000)
ret = 30 - (snr_val - 158000)*15/(900000 - 158000);
/* snr_val:31600~158000,ret:30~50 */
else if (snr_val > 31600)
ret = 50 - (snr_val - 31600)*20/(158000 - 31600);
/* snr_val:316~31600,ret:50~80 */
else if (snr_val > 316)
ret = 80 - (snr_val - 316)*30/(31600 - 316);
/* snr_val:0~316,ret:80~100 */
else
ret = 100 - (316 - snr_val)*20/316;
return ret;
#endif
}
int is_atvdemod_work(void)
{
int ret = 0;
if (atvdemod_state == ATVDEMOD_STATE_WORK)
ret = 1;
return ret;
}
int is_atvdemod_scan_mode(void)
{
return atvdemod_scan_mode;
}
//EXPORT_SYMBOL(is_atvdemod_scan_mode);
void set_atvdemod_scan_mode(int val)
{
atvdemod_scan_mode = val;
}
int get_atvdemod_state(void)
{
return atvdemod_state;
}
void set_atvdemod_state(int state)
{
atvdemod_state = state;
}
int atv_demod_enter_mode(void)
{
int err_code = 0;
#if 0
if (atvdemod_state == ATVDEMOD_STATE_WORK)
return 0;
#endif
if (amlatvdemod_devp->pin_name != NULL)
amlatvdemod_devp->pin =
devm_pinctrl_get_select(amlatvdemod_devp->dev,
amlatvdemod_devp->pin_name);
adc_set_pll_cntl(1, 0x1, NULL);
usleep_range(2000, 2100);
atvdemod_clk_init();
err_code = atvdemod_init();
if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) {
aud_demod_clk_gate(1);
atvauddemod_init();
}
if (err_code) {
pr_dbg("[amlatvdemod..]%s init atvdemod error.\n", __func__);
return err_code;
}
/* set_aft_thread_enable(1, 0); */
//memset(&(amlatvdemod_devp->parm), 0, sizeof(amlatvdemod_devp->parm));
atvdemod_state = ATVDEMOD_STATE_WORK;
pr_info("%s: OK\n", __func__);
return 0;
}
int atv_demod_leave_mode(void)
{
if (atvdemod_state == ATVDEMOD_STATE_IDEL)
return 0;
/* set_aft_thread_enable(0, 0); */
atvdemod_uninit();
if (amlatvdemod_devp->pin != NULL) {
devm_pinctrl_put(amlatvdemod_devp->pin);
amlatvdemod_devp->pin = NULL;
}
adc_set_pll_cntl(0, 0x1, NULL);
if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
aud_demod_clk_gate(0);
//memset(&(amlatvdemod_devp->parm), 0, sizeof(amlatvdemod_devp->parm));
atvdemod_state = ATVDEMOD_STATE_IDEL;
pr_info("%s: OK\n", __func__);
return 0;
}
static void atv_demod_set_params(struct dvb_frontend *fe,
struct analog_parameters *params)
{
int ret = -1;
u32 if_info[2] = { 0 };
struct atv_demod_priv *priv = fe->analog_demod_priv;
struct aml_atvdemod_parameters *atvdemod_param = &priv->atvdemod_param;
priv->standby = false;
atvdemod_param->param.frequency = params->frequency;
atvdemod_param->param.mode = params->mode;
atvdemod_param->param.audmode = params->audmode;
atvdemod_param->param.std = params->std;
/* afc tune disable,must cancel wq before set tuner freq*/
/* afc_timer_disable(); */
if (fe->ops.tuner_ops.set_analog_params)
ret = fe->ops.tuner_ops.set_analog_params(fe, params);
if (fe->ops.tuner_ops.get_if_frequency)
ret = fe->ops.tuner_ops.get_if_frequency(fe, if_info);
atvdemod_param->if_inv = if_info[0];
atvdemod_param->if_freq = if_info[1];
if ((atvdemod_param->param.std != amlatvdemod_devp->std) ||
(atvdemod_param->tuner_id == AM_TUNER_R840) ||
(atvdemod_param->tuner_id == AM_TUNER_SI2151) ||
(atvdemod_param->tuner_id == AM_TUNER_MXL661)) {
/* open AGC if needed */
if (amlatvdemod_devp->pin != NULL)
devm_pinctrl_put(amlatvdemod_devp->pin);
if (amlatvdemod_devp->pin_name)
amlatvdemod_devp->pin =
devm_pinctrl_get_select(amlatvdemod_devp->dev,
amlatvdemod_devp->pin_name);
#if 0
last_frq = atvdemod_param->param.frequency;
last_std = atvdemod_param->param.std;
#endif
if (atvdemod_param->param.std != amlatvdemod_devp->std) {
amlatvdemod_devp->std = atvdemod_param->param.std;
amlatvdemod_devp->if_freq = atvdemod_param->if_freq;
amlatvdemod_devp->if_inv = atvdemod_param->if_inv;
amlatvdemod_devp->tuner_id = atvdemod_param->tuner_id;
atv_dmd_set_std();
} else {
atv_dmd_soft_reset();
return;
}
if (!is_atvdemod_scan_mode())
atvauddemod_init();
pr_info("[amlatvdemod..]%s set std color %lld, audio type %lld.\n",
__func__, amlatvdemod_devp->std, amlatvdemod_devp->std);
pr_info("[amlatvdemod..]%s set if_freq %d, if_inv %d.\n",
__func__, amlatvdemod_devp->if_freq,
amlatvdemod_devp->if_inv);
}
pr_err("%s: tuner_id = %d.\n", __func__, atvdemod_param->tuner_id);
}
static int atv_demod_has_signal(struct dvb_frontend *fe, u16 *signal)
{
int vpll_lock = 0;
int line_lock = 0;
retrieve_vpll_carrier_lock(&vpll_lock);
/* add line lock status for atv scan */
retrieve_vpll_carrier_line_lock(&line_lock);
if ((vpll_lock & 0x1) == 0 && line_lock == 0) {
*signal = V4L2_HAS_LOCK;
pr_info("visual carrier lock:locked\n");
} else {
*signal = V4L2_TIMEDOUT;
pr_info("visual carrier lock:unlocked\n");
}
pr_err("%s.\n", __func__);
return 0;
}
static void atv_demod_standby(struct dvb_frontend *fe)
{
if (get_atvdemod_state() != ATVDEMOD_STATE_IDEL) {
atv_demod_leave_mode();
set_atvdemod_state(ATVDEMOD_STATE_SLEEP);
}
pr_info("%s: OK\n", __func__);
}
static void atv_demod_tuner_status(struct dvb_frontend *fe)
{
pr_err("%s.\n", __func__);
}
static int atv_demod_get_afc(struct dvb_frontend *fe, s32 *afc)
{
*afc = retrieve_vpll_carrier_afc();
pr_info("%s: afc %d.\n", __func__, *afc);
return 0;
}
static void atv_demod_release(struct dvb_frontend *fe)
{
struct atv_demod_priv *priv = fe->analog_demod_priv;
atv_demod_leave_mode();
mutex_lock(&atv_demod_list_mutex);
if (priv)
hybrid_tuner_release_state(priv);
mutex_unlock(&atv_demod_list_mutex);
fe->analog_demod_priv = NULL;
pr_err("%s.\n", __func__);
}
static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg)
{
int *state = (int *) priv_cfg;
if (!state) {
pr_err("%s state == NULL.\n", __func__);
return -1;
}
mutex_lock(&atv_demod_list_mutex);
if (*state == AML_ATVDEMOD_INIT) {
atv_demod_enter_mode();
if (fe->ops.tuner_ops.init)
fe->ops.tuner_ops.init(fe);
} else if (*state == AML_ATVDEMOD_UNINIT) {
atv_demod_leave_mode();
if (fe->ops.tuner_ops.release)
fe->ops.tuner_ops.release(fe);
} else if (*state == AML_ATVDEMOD_RESUME) {
if (get_atvdemod_state() == ATVDEMOD_STATE_SLEEP)
atv_demod_enter_mode();
if (fe->ops.tuner_ops.resume)
fe->ops.tuner_ops.resume(fe);
}
mutex_unlock(&atv_demod_list_mutex);
pr_err("%s done.\n", __func__);
return 0;
}
static struct analog_demod_ops atvdemod_ops = {
.info = {
.name = "atv_demod",
},
.set_params = atv_demod_set_params,
.has_signal = atv_demod_has_signal,
.standby = atv_demod_standby,
.tuner_status = atv_demod_tuner_status,
.get_afc = atv_demod_get_afc,
.release = atv_demod_release,
.set_config = atv_demod_set_config,
.i2c_gate_ctrl = NULL,
};
struct dvb_frontend *aml_atvdemod_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c_adap, u8 i2c_addr, u32 tuner_id)
{
int instance = 0;
struct atv_demod_priv *priv = NULL;
mutex_lock(&atv_demod_list_mutex);
instance = hybrid_tuner_request_state(struct atv_demod_priv, priv,
hybrid_tuner_instance_list,
i2c_adap, i2c_addr, DEVICE_NAME);
priv->atvdemod_param.tuner_id = tuner_id;
switch (instance) {
case 0:
mutex_unlock(&atv_demod_list_mutex);
return NULL;
case 1:
fe->analog_demod_priv = priv;
priv->standby = true;
pr_info("aml_atvdemod found\n");
break;
default:
fe->analog_demod_priv = priv;
break;
}
mutex_unlock(&atv_demod_list_mutex);
fe->ops.info.type = FE_ANALOG;
memcpy(&fe->ops.analog_ops, &atvdemod_ops,
sizeof(struct analog_demod_ops));
switch (tuner_id) {
case AM_TUNER_R840:
break;
case AM_TUNER_SI2151:
v4l2_attach(si2151_attach, fe, i2c_adap, i2c_addr);
break;
case AM_TUNER_MXL661:
v4l2_attach(mxl661_attach, fe, i2c_adap, i2c_addr);
break;
}
return fe;
}

View File

@@ -0,0 +1,45 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ATV_DEMOD_OPS_H__
#define __ATV_DEMOD_OPS_H__
#define AML_ATVDEMOD_RESUME 0x2
#define AML_ATVDEMOD_INIT 0x1
#define AML_ATVDEMOD_UNINIT 0x0
#include "drivers/media/dvb-core/dvb_frontend.h"
#include "drivers/media/tuners/tuner-i2c.h"
#include "atv_demod_driver.h"
struct atv_demod_priv {
struct tuner_i2c_props i2c_props;
struct list_head hybrid_tuner_instance_list;
bool standby;
struct aml_atvdemod_parameters atvdemod_param;
};
extern int atv_demod_enter_mode(void);
struct dvb_frontend *aml_atvdemod_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c_adap, u8 i2c_addr, u32 tuner_id);
extern struct dvb_frontend *mxl661_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c_adap, u8 i2c_addr);
extern struct dvb_frontend *si2151_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c_adap, u8 i2c_addr);
#endif /* __ATV_DEMOD_OPS_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ATV_DEMOD_V4L2_H__
#define __ATV_DEMOD_V4L2_H__
#include <media/v4l2-device.h>
#include "drivers/media/dvb-core/dvb_frontend.h"
/** generic attach function. */
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
#define v4l2_attach(FUNCTION, ARGS...) ({ \
void *__r = NULL; \
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
if (__a) { \
__r = (void *) __a(ARGS); \
if (__r == NULL) \
symbol_put(FUNCTION); \
} else { \
pr_err("V4L2_FE: Unable to find " \
"symbol "#FUNCTION"()\n"); \
} \
__r; \
})
#else
#define v4l2_attach(FUNCTION, ARGS...) ({ \
FUNCTION(ARGS); \
})
#endif /* CONFIG_MEDIA_ATTACH */
#define V4L2_FE_NO_EXIT 0
#define V4L2_FE_NORMAL_EXIT 1
#define V4L2_FE_DEVICE_REMOVED 2
#define V4L2FE_STATE_IDLE 1
#define V4L2FE_STATE_RETUNE 2
#define V4L2FE_STATE_TUNING_FAST 4
#define V4L2FE_STATE_TUNING_SLOW 8
#define V4L2FE_STATE_TUNED 16
#define V4L2FE_STATE_ZIGZAG_FAST 32
#define V4L2FE_STATE_ZIGZAG_SLOW 64
#define V4L2FE_STATE_DISEQC 128
#define V4L2FE_STATE_ERROR 256
#define V4L2FE_STATE_WAITFORLOCK (V4L2FE_STATE_TUNING_FAST |\
V4L2FE_STATE_TUNING_SLOW | V4L2FE_STATE_ZIGZAG_FAST |\
V4L2FE_STATE_ZIGZAG_SLOW | V4L2FE_STATE_DISEQC)
#define V4L2FE_STATE_SEARCHING_FAST (V4L2FE_STATE_TUNING_FAST |\
V4L2FE_STATE_ZIGZAG_FAST)
#define V4L2FE_STATE_SEARCHING_SLOW (V4L2FE_STATE_TUNING_SLOW |\
V4L2FE_STATE_ZIGZAG_SLOW)
#define V4L2FE_STATE_LOSTLOCK (V4L2FE_STATE_ZIGZAG_FAST |\
V4L2FE_STATE_ZIGZAG_SLOW)
#define V4L2_SET_FRONTEND _IOW('V', 105, struct v4l2_analog_parameters)
#define V4L2_GET_FRONTEND _IOR('V', 106, struct v4l2_analog_parameters)
#define V4L2_GET_EVENT _IOR('V', 107, struct v4l2_frontend_event)
#define V4L2_SET_MODE _IO('V', 108)
struct v4l2_analog_parameters {
unsigned int frequency;
unsigned int audmode;
unsigned int soundsys; /*A2,BTSC,EIAJ,NICAM */
v4l2_std_id std;
unsigned int flag;
unsigned int afc_range;
unsigned int reserved;
};
enum v4l2_status {
V4L2_HAS_SIGNAL = 0x01, /* found something above the noise level */
V4L2_HAS_CARRIER = 0x02, /* found a DVB signal */
V4L2_HAS_VITERBI = 0x04, /* FEC is stable */
V4L2_HAS_SYNC = 0x08, /* found sync bytes */
V4L2_HAS_LOCK = 0x10, /* everything's working... */
V4L2_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */
V4L2_REINIT = 0x40, /* frontend was reinitialized, */
}; /* application is recommended to reset */
/* DiSEqC, tone and parameters */
enum v4l2_search {
V4L2_SEARCH_SUCCESS = (1 << 0),
V4L2_SEARCH_ASLEEP = (1 << 1),
V4L2_SEARCH_FAILED = (1 << 2),
V4L2_SEARCH_INVALID = (1 << 3),
V4L2_SEARCH_AGAIN = (1 << 4),
V4L2_SEARCH_ERROR = (1 << 31),
};
struct v4l2_frontend_event {
enum v4l2_status status;
struct v4l2_analog_parameters parameters;
};
#define MAX_EVENT 8
struct v4l2_fe_events {
struct v4l2_frontend_event events[MAX_EVENT];
int eventw;
int eventr;
int overflow;
wait_queue_head_t wait_queue;
struct mutex mtx;
};
struct v4l2_frontend_private {
struct v4l2_atvdemod_device *v4l2dev;
struct v4l2_fe_events events;
struct semaphore sem;
struct list_head list_head;
wait_queue_head_t wait_queue;
struct task_struct *thread;
unsigned long release_jiffies;
unsigned int exit;
unsigned int wakeup;
enum v4l2_status status;
unsigned int delay;
unsigned int state;
enum v4l2_search algo_status;
};
struct v4l2_adapter {
struct device *dev;
struct dvb_frontend fe;
struct i2c_client i2c;
unsigned int tuner_id;
};
struct v4l2_frontend {
struct v4l2_adapter *v4l2_ad;
void *frontend_priv;
void *tuner_priv;
void *analog_priv;
struct v4l2_analog_parameters params;
enum v4l2_search (*search)(struct v4l2_frontend *v4l2_fe);
};
struct v4l2_atvdemod_device {
char *name;
struct class *clsp;
struct device *dev;
struct v4l2_device v4l2_dev;
struct video_device *video_dev;
struct mutex lock;
struct i2c_client i2c;
unsigned int tuner_id;
enum v4l2_search (*search)(struct v4l2_atvdemod_device *dev);
};
int v4l2_resister_frontend(struct v4l2_adapter *v4l2_ad,
struct v4l2_frontend *v4l2_fe);
int v4l2_unresister_frontend(struct v4l2_frontend *v4l2_fe);
int v4l2_frontend_suspend(struct v4l2_frontend *v4l2_fe);
int v4l2_frontend_resume(struct v4l2_frontend *v4l2_fe);
#endif // __ATV_DEMOD_V4L2_H__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/* atvauddemod_func.h */
#ifndef __ATVAUDDEMOD_H_
#define __ATVAUDDEMOD_H_
#include "aud_demod_reg.h"
extern int atvaudiodem_reg_read(unsigned int reg, unsigned int *val);
extern int atvaudiodem_reg_write(unsigned int reg, unsigned int val);
extern uint32_t adec_rd_reg(uint32_t addr);
extern void adec_wr_reg(uint32_t reg, uint32_t val);
extern int is_atvdemod_work(void);
int get_atvdemod_state(void);
void set_atvdemod_state(int state);
extern int aml_atvdemod_get_btsc_sap_mode(void);
extern void audio_mode_det(int mode);
void set_outputmode(uint32_t standard, uint32_t outmode);
void aud_demod_clk_gate(int on);
void configure_adec(int Audio_mode);
void adec_soft_reset(void);
void audio_thd_init(void);
void audio_thd_det(void);
void set_nicam_outputmode(uint32_t outmode);
void set_a2_eiaj_outputmode(uint32_t outmode);
void set_btsc_outputmode(uint32_t outmode);
void update_nicam_mode(int *nicam_flag, int *nicam_mono_flag,
int *nicam_stereo_flag, int *nicam_dual_flag);
void update_btsc_mode(int auto_en, int *stereo_flag, int *sap_flag);
void update_a2_eiaj_mode(int auto_en, int *stereo_flag, int *dual_flag);
#endif /* __ATVAUDDEMOD_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,323 @@
/*
* ATVDEMOD Device Driver
*
* Author: dezhi kong <dezhi.kong@amlogic.com>
*
*
* Copyright (C) 2014 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ATVDEMOD_FUN_H
#define __ATVDEMOD_FUN_H
/*#include "../aml_fe.h"*/
/*#include <linux/amlogic/tvin/tvin.h>*/
/*#include "../aml_fe.h"*/
#include <linux/amlogic/iomap.h>
struct dvb_frontend;
/*#define TVFE_APB_BASE_ADDR 0xd0046000*/
#define ATV_DMD_APB_BASE_ADDR 0xc8008000
#define ATV_DMD_APB_BASE_ADDR_GXTVBB 0xc8840000
#define HHI_ATV_DMD_SYS_CLK_CNTL 0x10f3
extern int atvdemod_debug_en;
extern unsigned int reg_23cf; /* IIR filter */
extern int broad_std_except_pal_m;
#define ATVDEMOD_INTERVAL (HZ/100) /*10ms, #define HZ 100*/
extern int amlatvdemod_reg_read(unsigned int reg, unsigned int *val);
extern int amlatvdemod_reg_write(unsigned int reg, unsigned int val);
extern int amlatvdemod_hiu_reg_read(unsigned int reg, unsigned int *val);
extern int amlatvdemod_hiu_reg_write(unsigned int reg, unsigned int val);
static inline uint32_t R_ATVDEMOD_REG(uint32_t reg)
{
unsigned int val;
amlatvdemod_reg_read(reg, &val);
return val;
}
static inline void W_ATVDEMOD_REG(uint32_t reg,
const uint32_t val)
{
amlatvdemod_reg_write(reg, val);
}
static inline void W_ATVDEMOD_BIT(uint32_t reg,
const uint32_t value,
const uint32_t start,
const uint32_t len)
{
W_ATVDEMOD_REG(reg, ((R_ATVDEMOD_REG(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}
static inline uint32_t R_ATVDEMOD_BIT(uint32_t reg,
const uint32_t start,
const uint32_t len)
{
uint32_t val;
val = ((R_ATVDEMOD_REG(reg) >> (start)) & ((1L << (len)) - 1));
return val;
}
static inline uint32_t R_HIU_REG(uint32_t reg)
{
unsigned int val;
amlatvdemod_hiu_reg_read(reg, &val);
return val;
}
static inline void W_HIU_REG(uint32_t reg,
const uint32_t val)
{
amlatvdemod_hiu_reg_write(reg, val);
}
static inline void W_HIU_BIT(uint32_t reg,
const uint32_t value,
const uint32_t start,
const uint32_t len)
{
W_HIU_REG(reg, ((R_HIU_REG(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}
static inline uint32_t R_HIU_BIT(uint32_t reg,
const uint32_t start,
const uint32_t len)
{
uint32_t val;
val = ((R_HIU_REG(reg) >> (start)) & ((1L << (len)) - 1));
return val;
}
enum broadcast_standard_e {
ATVDEMOD_STD_NTSC = 0,
ATVDEMOD_STD_NTSC_J,
ATVDEMOD_STD_PAL_M,
ATVDEMOD_STD_PAL_BG,
ATVDEMOD_STD_DTV,
ATVDEMOD_STD_SECAM_DK2,
ATVDEMOD_STD_SECAM_DK3,
ATVDEMOD_STD_PAL_BG_NICAM,
ATVDEMOD_STD_PAL_DK_CHINA,
ATVDEMOD_STD_SECAM_L,
ATVDEMOD_STD_PAL_I,
ATVDEMOD_STD_PAL_DK1,
ATVDEMOD_STD_MAX,
};
enum gde_curve_e {
ATVDEMOD_CURVE_M = 0,
ATVDEMOD_CURVE_A,
ATVDEMOD_CURVE_B,
ATVDEMOD_CURVE_CHINA,
ATVDEMOD_CURVE_MAX,
};
enum sound_format_e {
ATVDEMOD_SOUND_STD_MONO = 0,
ATVDEMOD_SOUND_STD_NICAM,
ATVDEMOD_SOUND_STD_MAX,
};
extern void atv_dmd_wr_reg(unsigned char block, unsigned char reg,
unsigned long data);
extern unsigned long atv_dmd_rd_reg(unsigned char block, unsigned char reg);
extern unsigned long atv_dmd_rd_byte(unsigned long block_address,
unsigned long reg_addr);
extern unsigned long atv_dmd_rd_word(unsigned long block_address,
unsigned long reg_addr);
extern unsigned long atv_dmd_rd_long(unsigned long block_address,
unsigned long reg_addr);
extern void atv_dmd_wr_long(unsigned long block_address,
unsigned long reg_addr,
unsigned long data);
extern void atv_dmd_wr_word(unsigned long block_address,
unsigned long reg_addr,
unsigned long data);
extern void atv_dmd_wr_byte(unsigned long block_address,
unsigned long reg_addr,
unsigned long data);
extern void set_audio_gain_val(int val);
extern void set_video_gain_val(int val);
extern void atv_dmd_soft_reset(void);
extern void atv_dmd_input_clk_32m(void);
extern void read_version_register(void);
extern void check_communication_interface(void);
extern void power_on_receiver(void);
extern void atv_dmd_misc(void);
extern void configure_receiver(int Broadcast_Standard,
unsigned int Tuner_IF_Frequency,
int Tuner_Input_IF_inverted, int GDE_Curve,
int sound_format);
extern int atvdemod_clk_init(void);
extern int atvdemod_init(void);
extern void atvdemod_uninit(void);
extern void atv_dmd_set_std(void);
extern void retrieve_adc_power(int *adc_level);
extern void retrieve_vpll_carrier_lock(int *lock);
extern void retrieve_vpll_carrier_line_lock(int *lock);
extern void retrieve_vpll_carrier_audio_power(int *power);
extern void retrieve_video_lock(int *lock);
extern int retrieve_vpll_carrier_afc(void);
extern int get_atvdemod_snr_val(void);
extern int aml_atvdemod_get_snr(struct dvb_frontend *fe);
/*atv demod block address*/
/*address interval is 4, because it's 32bit interface,*/
/*but the address is in byte */
#define ATV_DMD_TOP_CTRL 0x0
#define ATV_DMD_TOP_CTRL1 0x4
#define ATV_DMD_RST_CTRL 0x8
#define APB_BLOCK_ADDR_SYSTEM_MGT 0x0
#define APB_BLOCK_ADDR_AA_LP_NOTCH 0x1
#define APB_BLOCK_ADDR_MIXER_1 0x2
#define APB_BLOCK_ADDR_MIXER_3 0x3
#define APB_BLOCK_ADDR_ADC_SE 0x4
#define APB_BLOCK_ADDR_PWR_ANL 0x5
#define APB_BLOCK_ADDR_CARR_RCVY 0x6
#define APB_BLOCK_ADDR_FE_DROOP_MDF 0x7
#define APB_BLOCK_ADDR_SIF_IC_STD 0x8
#define APB_BLOCK_ADDR_SIF_STG_2 0x9
#define APB_BLOCK_ADDR_SIF_STG_3 0xa
#define APB_BLOCK_ADDR_IC_AGC 0xb
#define APB_BLOCK_ADDR_DAC_UPS 0xc
#define APB_BLOCK_ADDR_GDE_EQUAL 0xd
#define APB_BLOCK_ADDR_VFORMAT 0xe
#define APB_BLOCK_ADDR_VDAGC 0xf
#define APB_BLOCK_ADDR_VERS_REGISTER 0x10
#define APB_BLOCK_ADDR_INTERPT_MGT 0x11
#define APB_BLOCK_ADDR_ADC_MGR 0x12
#define APB_BLOCK_ADDR_GP_VD_FLT 0x13
#define APB_BLOCK_ADDR_CARR_DMD 0x14
#define APB_BLOCK_ADDR_SIF_VD_IF 0x15
#define APB_BLOCK_ADDR_VD_PKING 0x16
#define APB_BLOCK_ADDR_FE_DR_SMOOTH 0x17
#define APB_BLOCK_ADDR_AGC_PWM 0x18
#define APB_BLOCK_ADDR_DAC_UPS_24M 0x19
#define APB_BLOCK_ADDR_VFORMAT_DP 0x1a
#define APB_BLOCK_ADDR_VD_PKING_DAC 0x1b
#define APB_BLOCK_ADDR_MONO_PROC 0x1c
#define APB_BLOCK_ADDR_TOP 0x1d
#define SLAVE_BLOCKS_NUMBER 0x1d /*indeed totals 0x1e, adding top*/
/*Broadcast_Standard*/
/* 0: NTSC*/
/* 1: NTSC-J*/
/* 2: PAL-M,*/
/* 3: PAL-BG*/
/* 4: DTV*/
/* 5: SECAM- DK2*/
/* 6: SECAM -DK3*/
/* 7: PAL-BG, NICAM*/
/* 8: PAL-DK-CHINA*/
/* 9: SECAM-L / SECAM-DK3*/
/* 10: PAL-I*/
/* 11: PAL-DK1*/
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC 0
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_J 1
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_M 2
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG 3
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_DTV 4
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK2 5
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_DK3 6
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_BG_NICAM 7
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK 8
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_SECAM_L 9
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_I 10
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_PAL_DK1 11
/* new add @20150813 begin */
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_DK 12
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_BG 13
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_I 14
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_NTSC_M 15
/* new add @20150813 end */
/*GDE_Curve*/
/* 0: CURVE-M*/
/* 1: CURVE-A*/
/* 2: CURVE-B*/
/* 3: CURVE-CHINA*/
/* 4: BYPASS*/
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_M 0
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_A 1
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_B 2
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_CHINA 3
#define AML_ATV_DEMOD_VIDEO_MODE_PROP_CURVE_BYPASS 4
#define HHI_GCLK_MPEG0 (0x1050)
/*sound format 0: MONO;1:NICAM*/
#define AML_ATV_DEMOD_SOUND_MODE_PROP_MONO 0
#define AML_ATV_DEMOD_SOUND_MODE_PROP_NICAM 1
/*
* freq_hz:hs_freq
* freq_hz_cvrt=hs_freq/0.23841858
* vs_freq==50,freq_hz=15625;freq_hz_cvrt=0xffff
* vs_freq==60,freq_hz=15734,freq_hz_cvrt=0x101c9
*/
#define AML_ATV_DEMOD_FREQ_50HZ_VERT 0xffff /*65535*/
#define AML_ATV_DEMOD_FREQ_60HZ_VERT 0x101c9 /*65993*/
#define CARR_AFC_DEFAULT_VAL 0xffff
enum amlatvdemod_snr_level_e {
very_low = 1,
low,
ok_minus,
ok_plus,
high,
};
enum audio_detect_mode {
AUDIO_AUTO_DETECT = 0,
AUDIO_MANUAL_DETECT,
};
#if 0
struct amlatvdemod_device_s {
struct class *clsp;
struct device *dev;
struct analog_parameters parm;
int fre_offset;
struct pinctrl *pin;
const char *pin_name;
};
#endif
extern int amlatvdemod_hiu_reg_read(unsigned int reg, unsigned int *val);
extern void aml_audio_overmodulation(int enable);
extern void amlatvdemod_set_std(int val);
extern void aml_fix_PWM_adjust(int enable);
extern void aml_audio_valume_gain_set(unsigned int audio_gain);
extern unsigned int aml_audio_valume_gain_get(void);
extern void aml_atvdemod_overmodule_det(void);
extern int aml_audiomode_autodet(struct dvb_frontend *fe);
extern void retrieve_frequency_offset(int *freq_offset);
extern void retrieve_field_lock(int *lock);
extern int aml_atvdemod_get_snr_ex(void);
extern void set_atvdemod_scan_mode(int val);
extern int atvauddemod_init(void);
extern void atvauddemod_set_outputmode(void);
/*from amldemod/amlfrontend.c*/
extern int vdac_enable_check_dtv(void);
#endif /* __ATVDEMOD_FUN_H */

View File

@@ -0,0 +1,337 @@
#ifndef AUD_DEMOD_REG_H
#define AUD_DEMOD_REG_H
#define ADEC_CTRL 0x010
#define FREQ0_CTRL 0x011
#define FREQ1_CTRL 0x012
#define ID_FREQ_STEREO_CTRL 0x013
#define ID_FREQ_DUAL_CTRL 0x014
#define ID_FREQ_CARRIER_CTRL 0x015
#define DEMOD_GAIN_CTRL 0x016
#define BTSC_BYPASS_CTRL 0x017
#define EXPANDER_SPEC_ADJ 0x018
#define EXPANDER_GAIN_ADJ 0x019
#define LMR_GAIN_ADJ 0x01a
#define SAP_GAIN_ADJ 0x01b
#define LPR_GAIN_ADJ 0x01c
#define BTSC_STEREO_THD 0x01d
#define DELAY_COMP_CRTL 0x01e
#define EXPANDER_B_CTRL 0x01f
#define EXPANDER_B2C_ADJ 0x020
#define TEST_SEL_CTRL 0x021
#define IIR_SPEED_CTRL 0x022
#define STEREO_DET_THD 0x023
#define DUAL_DET_THD 0x024
#define SAP_DET_THD 0x025
#define MODE_DET_CNT_THD 0x026
#define ADEC_RESET 0x027
#define DDC_FIR_COEF0_0 0x030
#define DDC_FIR_COEF0_1 0x031
#define DDC_FIR_COEF0_2 0x032
#define DDC_FIR_COEF0_3 0x033
#define DDC_FIR_COEF0_4 0x034
#define DDC_FIR_COEF0_5 0x035
#define DDC_FIR_COEF0_6 0x036
#define DDC_FIR_COEF0_7 0x037
#define DDC_FIR_COEF0_8 0x038
#define DDC_FIR_COEF0_9 0x039
#define DDC_FIR_COEF0_10 0x03a
#define DDC_FIR_COEF0_11 0x03b
#define DDC_FIR_COEF0_12 0x03c
#define DDC_FIR_COEF0_13 0x03d
#define DDC_FIR_COEF0_14 0x03e
#define DDC_FIR_COEF0_15 0x03f
#define DDC_FIR_COEF0_16 0x040
#define DDC_FIR_COEF1_0 0x041
#define DDC_FIR_COEF1_1 0x042
#define DDC_FIR_COEF1_2 0x043
#define DDC_FIR_COEF1_3 0x044
#define DDC_FIR_COEF1_4 0x045
#define DDC_FIR_COEF1_5 0x046
#define DDC_FIR_COEF1_6 0x047
#define DDC_FIR_COEF1_7 0x048
#define DDC_FIR_COEF1_8 0x049
#define DDC_FIR_COEF1_9 0x04a
#define DDC_FIR_COEF1_10 0x04b
#define DDC_FIR_COEF1_11 0x04c
#define DDC_FIR_COEF1_12 0x04d
#define DDC_FIR_COEF1_13 0x04e
#define DDC_FIR_COEF1_14 0x04f
#define DDC_FIR_COEF1_15 0x050
#define DDC_FIR_COEF1_16 0x051
#define FILTER_00_0 0x052
#define FILTER_00_1 0x053
#define FILTER_00_2 0x054
#define FILTER_01_0 0x055
#define FILTER_01_1 0x056
#define FILTER_01_2 0x057
#define FILTER_02_0 0x058
#define FILTER_02_1 0x059
#define FILTER_02_2 0x05a
#define FILTER_03_0 0x05b
#define FILTER_03_1 0x05c
#define FILTER_03_2 0x05d
#define FILTER_04_0 0x05e
#define FILTER_04_1 0x05f
#define FILTER_04_2 0x060
#define FILTER_05_0 0x061
#define FILTER_05_1 0x062
#define FILTER_05_2 0x063
#define FILTER_06_0 0x064
#define FILTER_06_1 0x065
#define FILTER_06_2 0x066
#define FILTER_07_0 0x067
#define FILTER_07_1 0x068
#define FILTER_07_2 0x069
#define FILTER_08_0 0x06a
#define FILTER_08_1 0x06b
#define FILTER_08_2 0x06c
#define FILTER_09_0 0x06d
#define FILTER_09_1 0x06e
#define FILTER_09_2 0x06f
#define FILTER_10_0 0x070
#define FILTER_10_1 0x071
#define FILTER_10_2 0x072
#define FILTER_11_0 0x073
#define FILTER_11_1 0x074
#define FILTER_11_2 0x075
#define FILTER_12_0 0x076
#define FILTER_12_1 0x077
#define FILTER_12_2 0x078
#define FILTER_13_0 0x079
#define FILTER_13_1 0x07a
#define FILTER_13_2 0x07b
#define FILTER_14_0 0x07c
#define FILTER_14_1 0x07d
#define FILTER_14_2 0x07e
#define FILTER_15_0 0x07f
#define FILTER_15_1 0x080
#define FILTER_15_2 0x081
#define DBX_FILTER_01_0 0x085
#define DBX_FILTER_01_1 0x086
#define DBX_FILTER_01_2 0x087
#define DBX_FILTER_02_0 0x088
#define DBX_FILTER_02_1 0x089
#define DBX_FILTER_02_2 0x08a
#define DBX_FILTER_03_0 0x08b
#define DBX_FILTER_03_1 0x08c
#define DBX_FILTER_03_2 0x08d
#define DBX_FILTER_04_0 0x08e
#define DBX_FILTER_04_1 0x08f
#define DBX_FILTER_04_2 0x090
#define DBX_FILTER_05_0 0x091
#define DBX_FILTER_05_1 0x092
#define DBX_FILTER_05_2 0x093
#define DBX_FILTER_06_0 0x094
#define DBX_FILTER_06_1 0x095
#define DBX_FILTER_06_2 0x096
#define DBX_FILTER_07_0 0x097
#define DBX_FILTER_07_1 0x098
#define DBX_FILTER_07_2 0x099
#define DBX_FILTER_08_0 0x09a
#define DBX_FILTER_08_1 0x09b
#define DBX_FILTER_08_2 0x09c
#define BB_COEF0_A_0 0x0a0
#define BB_COEF0_A_1 0x0a1
#define BB_COEF0_A_2 0x0a2
#define BB_COEF0_A_3 0x0a3
#define BB_COEF1_A_0 0x0a4
#define BB_COEF1_A_1 0x0a5
#define BB_COEF1_A_2 0x0a6
#define BB_COEF1_A_3 0x0a7
#define BB_COEF2_A_0 0x0a8
#define BB_COEF2_A_1 0x0a9
#define BB_COEF2_A_2 0x0aa
#define BB_COEF2_A_3 0x0ab
#define BB_COEF0_B_0 0x0ac
#define BB_COEF0_B_1 0x0ad
#define BB_COEF0_B_2 0x0ae
#define BB_COEF0_B_3 0x0af
#define BB_COEF1_B_0 0x0b0
#define BB_COEF1_B_1 0x0b1
#define BB_COEF1_B_2 0x0b2
#define BB_COEF1_B_3 0x0b3
#define BB_COEF2_B_0 0x0b4
#define BB_COEF2_B_1 0x0b5
#define BB_COEF2_B_2 0x0b6
#define BB_COEF2_B_3 0x0b7
#define MUTE_THD0 0x0b8
#define MUTE_THD1 0x0b9
#define MUTE_THD2 0x0ba
#define NOISE_THD0 0x0bb
#define NOISE_THD1 0x0bc
#define NOISE_THD2 0x0bd
#define BB_SPEED 0x0be
#define SRC_CTRL0 0x0c0
#define SRC_CTRL1 0x0c1
#define SRC_CTRL2 0x0c2
#define SRC_CTRL3 0x0c3
#define SRC_CTRL4 0x0c4
#define SRC_CTRL5 0x0c5
#define SRC_CTRL6 0x0c6
#define SRC_CTRL7 0x0c7
#define SRC_CTRL8 0x0c8
#define SRC_CTRL9 0x0c9
#define THD_P0 0x0d0
#define THD_M0 0x0d1
#define THD_OV0 0x0d2
#define THD_CNT0 0x0d3
#define CNT_MAX0 0x0d4
#define THD_P1 0x0d5
#define THD_M1 0x0d6
#define THD_OV1 0x0d7
#define THD_CNT1 0x0d8
#define CNT_MAX1 0x0d9
#define OV_CNT_REPORT 0x0da
#define OV_FLAG_REPORT 0x0db
#define PILOT_BIAS_REPORT 0x0f0
#define STEREO_LEVEL_REPORT 0x0f1
#define SNR_REPORT 0x0f2
#define SNR_SAP_REPORT 0x0f3
#define POWER_REPORT 0x0f4
#define DC_REPORT 0x0f5
#define CARRIER_MAG_REPORT 0x0f6
#define BTSC_AB_REPORT 0x0f7
#define AUDIO_MODE_REPORT 0x0f8
#define CTRL_SEL 0x0ff
#define FCLK 32e6
#define ADDR_ADEC_CTRL (ADEC_CTRL)
#define ADDR_BTSC_BYPASS_CTRL (BTSC_BYPASS_CTRL)
#define ADDR_EXPANDER_SPECTRAL_ADJ (EXPANDER_SPEC_ADJ)
#define ADDR_EXPANDER_GAIN_ADJ (EXPANDER_GAIN_ADJ)
#define ADDR_LMR_ADJ (LMR_GAIN_ADJ)
#define ADDR_SAP_ADJ (SAP_GAIN_ADJ)
#define ADDR_LPR_GAIN_ADJ (LPR_GAIN_ADJ)
#define ADDR_STEREO_THRESHOLD (BTSC_STEREO_THD)
#define ADDR_LPR_COMP_CTRL (DELAY_COMP_CRTL)
#define ADDR_EXPANDER_B_CTRL (EXPANDER_B_CTRL)
#define ADDR_EXPANDER_B2C_ADJ (EXPANDER_B2C_ADJ)
#define ADDR_TEST_SEL_CTRL (TEST_SEL_CTRL)
#define ADDR_SAP_FIR_COEF (DDC_FIR_COEF1_0)
#define ADDR_SAP_DTO (FREQ1_CTRL)
#define ADDR_DDC_FREQ0 (FREQ0_CTRL)
#define ADDR_DDC_FREQ1 (FREQ1_CTRL)
#define ADDR_DEMOD_GAIN (DEMOD_GAIN_CTRL)
#define ADDR_DDC_FIR0_COEF (DDC_FIR_COEF0_0)
#define ADDR_DDC_FIR1_COEF (DDC_FIR_COEF1_0)
#define ADDR_BB_FIR0_A_COEF (BB_COEF0_A_0)
#define ADDR_BB_FIR1_A_COEF (BB_COEF1_A_0)
#define ADDR_BB_FIR2_A_COEF (BB_COEF2_A_0)
#define ADDR_BB_FIR0_B_COEF (BB_COEF0_B_0)
#define ADDR_BB_FIR1_B_COEF (BB_COEF0_B_1)
#define ADDR_BB_FIR2_B_COEF (BB_COEF0_B_2)
#define ADDR_BB_MUTE_THRESHOLD0 (MUTE_THD0)
#define ADDR_BB_MUTE_THRESHOLD1 (MUTE_THD1)
#define ADDR_BB_MUTE_THRESHOLD2 (MUTE_THD2)
#define ADDR_BB_NOISE_THRESHOLD0 (NOISE_THD0)
#define ADDR_BB_NOISE_THRESHOLD1 (NOISE_THD1)
#define ADDR_BB_NOISE_THRESHOLD2 (NOISE_THD2)
#define ADDR_INDICATOR_STEREO_DTO (ID_FREQ_STEREO_CTRL)
#define ADDR_INDICATOR_DUAL_DTO (ID_FREQ_DUAL_CTRL)
#define ADDR_INDICATOR_CENTER_DTO (ID_FREQ_CARRIER_CTRL)
#define ADDR_IIR_LPR_15K_0 (FILTER_00_0)
#define ADDR_IIR_LPR_15K_1 (FILTER_01_0)
#define ADDR_IIR_LPR_15K_2 (FILTER_02_0)
#define ADDR_IIR_LPR_15K_3 (FILTER_03_0)
#define ADDR_IIR_LPR_15K_4 (FILTER_04_0)
#define ADDR_IIR_LMR_15K_0 (FILTER_05_0)
#define ADDR_IIR_LMR_15K_1 (FILTER_06_0)
#define ADDR_IIR_LMR_15K_2 (FILTER_07_0)
#define ADDR_IIR_LMR_15K_3 (FILTER_08_0)
#define ADDR_IIR_LMR_15K_4 (FILTER_09_0)
#define ADDR_IIR_LPR_DEEMPHASIS (FILTER_10_0)
#define ADDR_IIR_PILOT_0 (FILTER_11_0)
#define ADDR_IIR_PILOT_1 (FILTER_12_0)
#define ADDR_IIR_PILOT_2 (FILTER_13_0)
#define ADDR_IIR_LPR_COMP (FILTER_14_0)
#define ADDR_IIR_LMR_DEEMPHASIS (FILTER_15_0)
#define ADDR_IIR_FIXED_DEEM_0 (DBX_FILTER_01_0)
#define ADDR_IIR_FIXED_DEEM_1 (DBX_FILTER_02_0)
#define ADDR_IIR_FIXED_DEEM_2 (DBX_FILTER_03_0)
#define ADDR_IIR_Q_FILTER_0 (DBX_FILTER_04_0)
#define ADDR_IIR_Q_FILTER_1 (DBX_FILTER_05_0)
#define ADDR_IIR_Q_FILTER_2 (DBX_FILTER_06_0)
#define ADDR_IIR_P_FILTER_0 (DBX_FILTER_07_0)
#define ADDR_IIR_P_FILTER_1 (DBX_FILTER_08_0)
#define ADDR_IIR_SPEED_CTRL (IIR_SPEED_CTRL)
#define ADDR_SEL_CTRL (CTRL_SEL)
#define AUDIO_STANDARD_BTSC 0x00
#define AUDIO_STANDARD_EIAJ 0x01
#define AUDIO_STANDARD_A2_K 0x02
#define AUDIO_STANDARD_A2_BG 0x03
#define AUDIO_STANDARD_A2_DK1 0x04
#define AUDIO_STANDARD_A2_DK2 0x05
#define AUDIO_STANDARD_A2_DK3 0x06
#define AUDIO_STANDARD_NICAM_I 0x07
#define AUDIO_STANDARD_NICAM_BG 0x08
#define AUDIO_STANDARD_NICAM_L 0x09
#define AUDIO_STANDARD_NICAM_DK 0x0A
#define AUDIO_STANDARD_FM_USA 0x0B
#define AUDIO_STANDARD_FM_EU 0x0C
#define AUDIO_STANDARD_CHINA 0x0E
#define AUDIO_STANDARD_INDIAN 0x0F
#define AUDIO_STANDARD_BTSC_SA 0x10
#define AUDIO_STANDARD_MONO_ONLY 0x11
#define AUDIO_OUTMODE_MONO 0
#define AUDIO_OUTMODE_STEREO 1
#define AUDIO_OUTMODE_SAP_DUAL 2
#define AUDIO_OUTMODE_BTSC_MONO 0
#define AUDIO_OUTMODE_BTSC_STEREO 1
#define AUDIO_OUTMODE_BTSC_SAP 2
#define AUDIO_OUTMODE_EIAJ_MONO 0
#define AUDIO_OUTMODE_EIAJ_STEREO 1
#define AUDIO_OUTMODE_EIAJ_MAIN 2
#define AUDIO_OUTMODE_EIAJ_SUB 3
#define AUDIO_OUTMODE_EIAJ_MAIN_SUB 4
#define AUDIO_OUTMODE_A2_MONO 0
#define AUDIO_OUTMODE_A2_STEREO 1
#define AUDIO_OUTMODE_A2_DUAL_A 2
#define AUDIO_OUTMODE_A2_DUAL_B 3
#define AUDIO_OUTMODE_A2_DUAL_AB 4
#define AUDIO_OUTMODE_NICAM_MONO 0
#define AUDIO_OUTMODE_NICAM_MONO1 1
#define AUDIO_OUTMODE_NICAM_STEREO 2
#define AUDIO_OUTMODE_NICAM_DUAL_A 3
#define AUDIO_OUTMODE_NICAM_DUAL_B 4
#define AUDIO_OUTMODE_NICAM_DUAL_AB 5
#define AUDIO_DEEM_75US 0
#define AUDIO_DEEM_50US 1
#define AUDIO_DEEM_J17 2
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
#ifndef _Aud_Demod_Settings_h_
#define _Aud_Demod_Settings_h_
extern int M_DTO;
extern int A2K_DTO;
extern int BG_DTO;
extern int A2G_DTO;
extern int EIAJ_DTO;
extern int SAP_DTO;
extern int A2K_INDICATOR_DTO;
extern int A2K_STEREO_DTO;
extern int A2K_DUAL_DTO;
extern int A2G_INDICATOR_DTO;
extern int A2G_STEREO_DTO;
extern int A2G_DUAL_DTO;
extern int filter_25k[];
extern int filter_50k[];
extern int filter_75k[];
extern int filter_100k[];
extern int filter_125k[];
extern int filter_150k[];
extern int filter_200k[];
extern int filter_300k[];
extern int filter_400k[];
extern int filter_550k[];
extern int filter_sap_10k[];
extern int filter_sap_15k[];
extern int filter_sap_20k[];
extern int filter_sap_25k[];
extern int filter_sap_30k[];
extern int filter_sap_35k[];
extern int filter_sap_40k[];
extern int filter_sap_45k[];
extern int filter_sap_50k[];
extern int filter_sap_55k[];
extern int filter_sap_60k[];
extern int filter_bb_10k[];
extern int filter_bb_20k[];
extern int iir_10k[];
extern int iir_12k[];
extern int iir_13k[];
extern int iir_14k[];
extern int iir_15k[];
extern int iir_16k[];
extern int iir_18k[];
extern int iir_20k[];
extern int iir_lpr_0[];
extern int iir_lpr_1[];
extern int iir_lpr_2[];
extern int iir_lpr_3[];
extern int iir_lpr_4[];
extern int iir_sap_0[];
extern int iir_sap_1[];
extern int iir_sap_2[];
extern int iir_sap_3[];
extern int iir_sap_4[];
extern int iir_sap_0[];
extern int iir_sap_1[];
extern int iir_sap_2[];
extern int iir_sap_3[];
extern int iir_sap_4[];
extern int iir_sap_10k_0[];
extern int iir_sap_10k_1[];
extern int iir_sap_10k_2[];
extern int iir_sap_10k_3[];
extern int iir_sap_10k_4[];
extern int iir_sap_11k_0[];
extern int iir_sap_11k_1[];
extern int iir_sap_11k_2[];
extern int iir_sap_11k_3[];
extern int iir_sap_11k_4[];
extern int iir_sap_12k_0[];
extern int iir_sap_12k_1[];
extern int iir_sap_12k_2[];
extern int iir_sap_12k_3[];
extern int iir_sap_12k_4[];
extern int iir_sap_13k_0[];
extern int iir_sap_13k_1[];
extern int iir_sap_13k_2[];
extern int iir_sap_13k_3[];
extern int iir_sap_13k_4[];
extern int iir_sap_14k_0[];
extern int iir_sap_14k_1[];
extern int iir_sap_14k_2[];
extern int iir_sap_14k_3[];
extern int iir_sap_14k_4[];
extern int iir_sap_15k_0[];
extern int iir_sap_15k_1[];
extern int iir_sap_15k_2[];
extern int iir_sap_15k_3[];
extern int iir_sap_15k_4[];
extern int iir_sap_16k_0[];
extern int iir_sap_16k_1[];
extern int iir_sap_16k_2[];
extern int iir_sap_16k_3[];
extern int iir_sap_16k_4[];
extern int iir_sap_17k_0[];
extern int iir_sap_17k_1[];
extern int iir_sap_17k_2[];
extern int iir_sap_17k_3[];
extern int iir_sap_17k_4[];
extern int iir_sap_11_2k_0[];
extern int iir_sap_11_2k_1[];
extern int iir_sap_11_2k_2[];
extern int iir_sap_11_2k_3[];
extern int iir_sap_11_2k_4[];
extern int iir_sap_11_4k_0[];
extern int iir_sap_11_4k_1[];
extern int iir_sap_11_4k_2[];
extern int iir_sap_11_4k_3[];
extern int iir_sap_11_4k_4[];
extern int iir_sap_11_6k_0[];
extern int iir_sap_11_6k_1[];
extern int iir_sap_11_6k_2[];
extern int iir_sap_11_6k_3[];
extern int iir_sap_11_6k_4[];
extern int iir_sap_11_8k_0[];
extern int iir_sap_11_8k_1[];
extern int iir_sap_11_8k_2[];
extern int iir_sap_11_8k_3[];
extern int iir_sap_11_8k_4[];
extern int iir_sap_12_0k_0[];
extern int iir_sap_12_0k_1[];
extern int iir_sap_12_0k_2[];
extern int iir_sap_12_0k_3[];
extern int iir_sap_12_0k_4[];
extern int iir_sap_12_2k_0[];
extern int iir_sap_12_2k_1[];
extern int iir_sap_12_2k_2[];
extern int iir_sap_12_2k_3[];
extern int iir_sap_12_2k_4[];
extern int iir_sap_12_4k_0[];
extern int iir_sap_12_4k_1[];
extern int iir_sap_12_4k_2[];
extern int iir_sap_12_4k_3[];
extern int iir_sap_12_4k_4[];
extern int iir_sap_12_6k_0[];
extern int iir_sap_12_6k_1[];
extern int iir_sap_12_6k_2[];
extern int iir_sap_12_6k_3[];
extern int iir_sap_12_6k_4[];
extern int iir_sap_12_8k_0[];
extern int iir_sap_12_8k_1[];
extern int iir_sap_12_8k_2[];
extern int iir_sap_12_8k_3[];
extern int iir_sap_12_8k_4[];
extern int iir_sap_13_0k_0[];
extern int iir_sap_13_0k_1[];
extern int iir_sap_13_0k_2[];
extern int iir_sap_13_0k_3[];
extern int iir_sap_13_0k_4[];
extern int iir_sap_13_2k_0[];
extern int iir_sap_13_2k_1[];
extern int iir_sap_13_2k_2[];
extern int iir_sap_13_2k_3[];
extern int iir_sap_13_2k_4[];
extern int iir_sap_13_4k_0[];
extern int iir_sap_13_4k_1[];
extern int iir_sap_13_4k_2[];
extern int iir_sap_13_4k_3[];
extern int iir_sap_13_4k_4[];
extern int filter_sap_12k_1[];
extern int filter_sap_12k_2[];
extern int filter_sap_12k_4[];
extern int filter_sap_15k_2[];
extern int filter_sap_15k_4[];
#endif /* _Settings_h_ */

View File

@@ -118,7 +118,7 @@ unsigned int av1_plugin_state;
unsigned int av2_plugin_state;
#endif
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
static struct tvafe_info_s *g_tvafe_info;
#endif
@@ -200,7 +200,7 @@ void tvafe_cma_release(struct tvafe_dev_s *devp)
}
#endif
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
static int tvafe_get_v_fmt(void)
{
int fmt = 0;
@@ -295,7 +295,7 @@ int tvafe_dec_open(struct tvin_frontend_s *fe, enum tvin_port_e port)
/* set the flag to enabble ioctl access */
devp->flags |= TVAFE_FLAG_DEV_OPENED;
tvafe_clk_status = true;
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
g_tvafe_info = tvafe;
/* register aml_fe hook for atv search */
aml_fe_hook_cvd(tvafe_cvd2_get_atv_format, tvafe_cvd2_get_hv_lock,
@@ -457,7 +457,7 @@ void tvafe_dec_close(struct tvin_frontend_s *fe)
}
tvafe_clk_status = false;
/*del_timer_sync(&devp->timer);*/
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
g_tvafe_info = NULL;
/* register aml_fe hook for atv search */
aml_fe_hook_cvd(NULL, NULL, NULL);
@@ -1147,7 +1147,7 @@ static int tvafe_drv_probe(struct platform_device *pdev)
}
s_tvafe_data = (struct meson_tvafe_data *)match->data;
tvafe_pr_info("%s£¬cpu_id:%d,name:%s\n", __func__,
tvafe_pr_info("%s:cpu_id:%d,name:%s\n", __func__,
s_tvafe_data->cpu_id, s_tvafe_data->name);
tvafe_clktree_probe(&pdev->dev);

View File

@@ -811,6 +811,7 @@ int tvafe_adc_get_pll_flag(void)
mutex_unlock(&pll_mutex);
return ret;
}
EXPORT_SYMBOL(tvafe_adc_get_pll_flag);
/*
* tvafe init the whole module

View File

@@ -0,0 +1,19 @@
/*
* amlogic atv demod driver
*
* Author: nengwen.chen <nengwen.chen@amlogic.com>
*
*
* Copyright (C) 2018 Amlogic Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __AML_ATVDEMOD_H__
#define __AML_ATVDEMOD_H__
extern void aml_fe_get_atvaudio_state(int *state);
#endif /* __AML_ATVDEMOD_H__ */

View File

@@ -49,6 +49,9 @@
#ifdef CONFIG_AMLOGIC_MEDIA_TVIN_HDMI
#include <linux/amlogic/media/frame_provider/tvin/tvin.h>
#endif
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
#include <linux/amlogic/aml_atvdemod.h>
#endif
#include "i2s.h"
#include "audio_hw.h"
@@ -650,7 +653,7 @@ static int aml_get_hdmiin_audio_format(struct snd_kcontrol *kcontrol,
}
#endif
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
static const char *const atv_audio_is_stable[] = {
"false",
"true"
@@ -667,7 +670,7 @@ static int aml_get_atv_audio_stable(struct snd_kcontrol *kcontrol,
ucontrol->value.integer.value[0] = state;
return 0;
}
#endif /* CONFIG_AM_DVB */
#endif /* CONFIG_AMLOGIC_ATV_DEMOD */
#ifdef CONFIG_TVIN_VDIN
static const char *const av_audio_is_stable[] = {
"false",
@@ -733,7 +736,7 @@ static const struct snd_kcontrol_new aml_tv_controls[] = {
aml_get_atmos_audio_edid,
aml_set_atmos_audio_edid),
#endif
#ifdef CONFIG_AM_DVB
#ifdef CONFIG_AMLOGIC_ATV_DEMOD
SOC_ENUM_EXT("ATV audio stable", atv_audio_status_enum,
aml_get_atv_audio_stable,
NULL),