From 0bfca47943fe2fca5c1526cd539ff417a73eb1dd Mon Sep 17 00:00:00 2001 From: "nengwen.chen" Date: Tue, 17 Jul 2018 17:50:52 +0800 Subject: [PATCH] atv_demod: txl: add atv demod support for txl PD#168480: atv_demod: txl: add atv demod support for txl Change-Id: I793946253ec9860473bdd57cf979168d9903f5df Signed-off-by: nengwen.chen --- drivers/amlogic/atv_demod/atv_demod_driver.c | 72 ++++++++++++++++---- drivers/amlogic/atv_demod/atv_demod_driver.h | 4 +- drivers/amlogic/atv_demod/atv_demod_ops.c | 37 +++++----- drivers/amlogic/atv_demod/atvdemod_func.c | 39 ++++++++--- include/linux/amlogic/aml_atvdemod.h | 5 ++ 5 files changed, 113 insertions(+), 44 deletions(-) diff --git a/drivers/amlogic/atv_demod/atv_demod_driver.c b/drivers/amlogic/atv_demod/atv_demod_driver.c index c5ae058451fd..a5a5a1a4f7dc 100644 --- a/drivers/amlogic/atv_demod/atv_demod_driver.c +++ b/drivers/amlogic/atv_demod/atv_demod_driver.c @@ -204,12 +204,6 @@ static ssize_t aml_atvdemod_store(struct class *class, 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", 7)) { - 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", 7)) { data_snr_avg = aml_atvdemod_get_snr_ex(); pr_dbg("**********snr_cur:%d*********\n", data_snr_avg); @@ -400,12 +394,12 @@ static void aml_atvdemod_dt_parse(struct aml_atvdemod_device *pdev) ret = of_property_read_string(node, "pinctrl-names", &pdev->pin_name); if (ret) { - pdev->pin = NULL; + pdev->agc_pin = NULL; pr_err("can't find agc pinmux.\n"); } else { -#if 0 - amlatvdemod_devp->pin = devm_pinctrl_get_select( - &pdev->dev, pdev->pin_name); +#if 0 /* Get it when you actually use it */ + pdev->agc_pin = devm_pinctrl_get_select( + pdev->dev, pdev->pin_name); #endif pr_err("atvdemod agc pinmux name: %s\n", pdev->pin_name); @@ -429,6 +423,8 @@ static void aml_atvdemod_dt_parse(struct aml_atvdemod_device *pdev) pdev->tuner_id = AM_TUNER_SI2159; else if (!strncmp(str, "r840_tuner", 10)) pdev->tuner_id = AM_TUNER_R840; + else if (!strncmp(str, "r842_tuner", 10)) + pdev->tuner_id = AM_TUNER_R842; else pr_err("can't find tuner: %s.\n", str); } @@ -479,6 +475,12 @@ int aml_attach_demod_tuner(struct aml_atvdemod_device *dev) if (!dev->tuner_attached) { switch (dev->tuner_id) { case AM_TUNER_R840: + p = v4l2_attach(r840_attach, fe, + dev->i2c_adp, dev->i2c_addr); + break; + case AM_TUNER_R842: + p = v4l2_attach(r842_attach, fe, + dev->i2c_adp, dev->i2c_addr); break; case AM_TUNER_SI2151: p = v4l2_attach(si2151_attach, fe, @@ -552,6 +554,42 @@ static int aml_atvdemod_probe(struct platform_device *pdev) dev->demod_reg_base); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + pr_err("no hiu demod memory resource.\n"); + dev->hiu_reg_base = NULL; + } else { + size_io_reg = resource_size(res); + dev->hiu_reg_base = devm_ioremap_nocache( + &pdev->dev, res->start, size_io_reg); + if (!dev->hiu_reg_base) { + pr_err("hiu ioremap failed.\n"); + goto fail_get_resource; + } + + pr_info("hiu start = 0x%p, size = 0x%x, hiu_reg_base = 0x%p.\n", + (void *) res->start, size_io_reg, + dev->hiu_reg_base); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (!res) { + pr_err("no periphs demod memory resource.\n"); + dev->periphs_reg_base = NULL; + } else { + size_io_reg = resource_size(res); + dev->periphs_reg_base = devm_ioremap_nocache( + &pdev->dev, res->start, size_io_reg); + if (!dev->periphs_reg_base) { + pr_err("periphs ioremap failed.\n"); + goto fail_get_resource; + } + + pr_info("periphs start = 0x%p, size = 0x%x, periphs_reg_base = 0x%p.\n", + (void *) res->start, size_io_reg, + dev->periphs_reg_base); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 3); if (!res) { pr_err("no audio demod memory resource.\n"); dev->audio_reg_base = NULL; @@ -569,6 +607,7 @@ static int aml_atvdemod_probe(struct platform_device *pdev) dev->audio_reg_base); } +#if 0 /* form dts config */ if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) dev->hiu_reg_base = ioremap(0xff63c000, 0x2000); else @@ -582,11 +621,16 @@ static int aml_atvdemod_probe(struct platform_device *pdev) dev->periphs_reg_base = ioremap(0xc8834000, 0x2000); pr_info("periphs_reg_base = 0x%p.\n", dev->periphs_reg_base); +#endif - /* add for audio system control */ - dev->audio_demod_reg_base = ioremap(round_down(0xffd0d340, 0x3), 4); + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { + /* add for audio system control */ + dev->audio_demod_reg_base = ioremap( + round_down(0xffd0d340, 0x3), 4); - pr_info("audio_demod_reg_base = 0x%p.\n", dev->audio_demod_reg_base); + pr_info("audio_demod_reg_base = 0x%p.\n", + dev->audio_demod_reg_base); + } aml_atvdemod_dt_parse(dev); @@ -668,7 +712,7 @@ int aml_atvdemod_resume(struct platform_device *pdev) static const struct of_device_id aml_atvdemod_dt_match[] = { { - .compatible = "amlogic, aml_atvdemod", + .compatible = "amlogic, atv-demod", }, { }, diff --git a/drivers/amlogic/atv_demod/atv_demod_driver.h b/drivers/amlogic/atv_demod/atv_demod_driver.h index 1ae9ed5291a6..fca858ef45d7 100644 --- a/drivers/amlogic/atv_demod/atv_demod_driver.h +++ b/drivers/amlogic/atv_demod/atv_demod_driver.h @@ -48,9 +48,9 @@ struct aml_atvdemod_device { unsigned int if_inv; u64 std; unsigned int audmode; - int fre_offset; - struct pinctrl *pin; + + struct pinctrl *agc_pin; const char *pin_name; struct v4l2_frontend v4l2_fe; diff --git a/drivers/amlogic/atv_demod/atv_demod_ops.c b/drivers/amlogic/atv_demod/atv_demod_ops.c index bc7cf11cf9b4..12d58c851c66 100644 --- a/drivers/amlogic/atv_demod/atv_demod_ops.c +++ b/drivers/amlogic/atv_demod/atv_demod_ops.c @@ -460,7 +460,7 @@ int atv_demod_enter_mode(void) return 0; #endif if (amlatvdemod_devp->pin_name != NULL) - amlatvdemod_devp->pin = + amlatvdemod_devp->agc_pin = devm_pinctrl_get_select(amlatvdemod_devp->dev, amlatvdemod_devp->pin_name); @@ -501,9 +501,9 @@ int atv_demod_leave_mode(void) set_aft_thread_enable(0, 0); atvdemod_uninit(); - if (amlatvdemod_devp->pin != NULL) { - devm_pinctrl_put(amlatvdemod_devp->pin); - amlatvdemod_devp->pin = NULL; + if (amlatvdemod_devp->agc_pin != NULL) { + devm_pinctrl_put(amlatvdemod_devp->agc_pin); + amlatvdemod_devp->agc_pin = NULL; } vdac_enable(0, 1); @@ -553,17 +553,11 @@ static void atv_demod_set_params(struct dvb_frontend *fe, if ((p->param.std != amlatvdemod_devp->std) || (p->tuner_id == AM_TUNER_R840) || + (p->tuner_id == AM_TUNER_R842) || (p->tuner_id == AM_TUNER_SI2151) || (p->tuner_id == AM_TUNER_MXL661) || (p->tuner_id == AM_TUNER_SI2159)) { - /* 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 /* unused */ last_frq = p->param.frequency; last_std = p->param.std; @@ -849,7 +843,8 @@ static void atvdemod_fe_try_analog_format(struct v4l2_frontend *v4l2_fe, pr_dbg("get varify_cnt:%d, cnt:%d, std_bk:0x%x\n", varify_cnt, i, (unsigned int) std_bk); - if ((v4l2_fe->tuner_id == AM_TUNER_R840 + if (((v4l2_fe->tuner_id == AM_TUNER_R840 + || v4l2_fe->tuner_id == AM_TUNER_R842) && varify_cnt > 0) || varify_cnt > 3) break; @@ -1003,13 +998,15 @@ static int atvdemod_fe_afc_closer(struct v4l2_frontend *v4l2_fe, int minafcfreq, while (abs(afc) > AFC_BEST_LOCK) { if (tuner_id == AM_TUNER_SI2151 || tuner_id == AM_TUNER_SI2159 || - tuner_id == AM_TUNER_R840) + tuner_id == AM_TUNER_R840 || + tuner_id == AM_TUNER_R842) usleep_range(20 * 1000, 20 * 1000 + 100); else if (tuner_id == AM_TUNER_MXL661) usleep_range(30 * 1000, 30 * 1000 + 100); if (fe->ops.analog_ops.get_afc && ((tuner_id == AM_TUNER_R840) || + (tuner_id == AM_TUNER_R842) || (tuner_id == AM_TUNER_SI2151) || (tuner_id == AM_TUNER_SI2159) || (tuner_id == AM_TUNER_MXL661))) @@ -1237,8 +1234,9 @@ static enum v4l2_search atvdemod_fe_search(struct v4l2_frontend *v4l2_fe) /*from the current freq start, and set the afc_step*/ /*if step is 2Mhz,r840 will miss program*/ - if (slow_mode || (tuner_id == AM_TUNER_R840) - || (p->afc_range == ATV_AFC_1_0MHZ)) { + if (slow_mode || + (tuner_id == AM_TUNER_R840 || tuner_id == AM_TUNER_R842) || + (p->afc_range == ATV_AFC_1_0MHZ)) { pr_dbg("[%s] slow mode to search the channel\n", __func__); afc_step = ATV_AFC_1_0MHZ; } else if (!slow_mode) { @@ -1269,7 +1267,8 @@ static enum v4l2_search atvdemod_fe_search(struct v4l2_frontend *v4l2_fe) do { if (tuner_id == AM_TUNER_MXL661) { usleep_range(30 * 1000, 30 * 1000 + 100); - } else if (tuner_id == AM_TUNER_R840) { + } else if (tuner_id == AM_TUNER_R840 || + tuner_id == AM_TUNER_R842) { usleep_range(20 * 1000, 20 * 1000 + 100); fe->ops.tuner_ops.get_status(fe, &tuner_state); @@ -1282,10 +1281,12 @@ static enum v4l2_search atvdemod_fe_search(struct v4l2_frontend *v4l2_fe) tuner_status_cnt_local--; if (((ade_state == V4L2_HAS_LOCK || tuner_state == V4L2_HAS_LOCK) && - (tuner_id != AM_TUNER_R840)) || + (tuner_id != AM_TUNER_R840 && + tuner_id != AM_TUNER_R842)) || ((ade_state == V4L2_HAS_LOCK && tuner_state == V4L2_HAS_LOCK) && - (tuner_id == AM_TUNER_R840))) { + (tuner_id == AM_TUNER_R840 || + tuner_id == AM_TUNER_R842))) { pll_lock = true; break; } diff --git a/drivers/amlogic/atv_demod/atvdemod_func.c b/drivers/amlogic/atv_demod/atvdemod_func.c index 7596ffe2bf62..ec2d6196c392 100644 --- a/drivers/amlogic/atv_demod/atvdemod_func.c +++ b/drivers/amlogic/atv_demod/atvdemod_func.c @@ -349,7 +349,8 @@ void atv_dmd_misc(void) atv_dmd_wr_byte(0x0f, 0x45, 0x90); /*zhuangwei*/ atv_dmd_wr_long(0x0f, 0x44, 0x5c8808c1);/*zhuangwei*/ - if (amlatvdemod_devp->tuner_id == AM_TUNER_R840) { + if (amlatvdemod_devp->tuner_id == AM_TUNER_R840 || + amlatvdemod_devp->tuner_id == AM_TUNER_R842) { atv_dmd_wr_long(0x0f, 0x3c, reg_23cf);/*zhuangwei*/ /*guanzhong@20150804a*/ atv_dmd_wr_byte(APB_BLOCK_ADDR_SIF_STG_2, 0x00, 0x1); @@ -1059,7 +1060,8 @@ void configure_receiver(int Broadcast_Standard, unsigned int Tuner_IF_Frequency, atv_dmd_wr_long(APB_BLOCK_ADDR_ADC_SE, 0x0, 0x03180e0f); else atv_dmd_wr_long(APB_BLOCK_ADDR_ADC_SE, 0x0, 0x03150e0f); - if (amlatvdemod_devp->tuner_id == AM_TUNER_R840) { + if (amlatvdemod_devp->tuner_id == AM_TUNER_R840 || + amlatvdemod_devp->tuner_id == AM_TUNER_R842) { /*config pwm for tuner r840*/ atv_dmd_wr_byte(APB_BLOCK_ADDR_ADC_SE, 1, 0xf); } @@ -1336,7 +1338,8 @@ void configure_receiver(int Broadcast_Standard, unsigned int Tuner_IF_Frequency, atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0x04, 0xc8); /*26 dB dynamic range*/ atv_dmd_wr_byte(APB_BLOCK_ADDR_AGC_PWM, 0x09, 0xa); - if (amlatvdemod_devp->tuner_id == AM_TUNER_R840) { + if (amlatvdemod_devp->tuner_id == AM_TUNER_R840 || + amlatvdemod_devp->tuner_id == AM_TUNER_R842) { /*config pwm for tuner r840*/ atv_dmd_wr_long(APB_BLOCK_ADDR_AGC_PWM, 0, 0xc80); /* guanzhong for Tuner AGC shock */ @@ -1675,7 +1678,8 @@ void atvdemod_timer_handler(unsigned long arg) aud_std == AUDIO_STANDARD_BTSC) audio_mode_det(aud_mode); */ - set_outputmode(aud_std, aud_mode); + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + set_outputmode(aud_std, aud_mode); if (non_std_onoff) atv_dmd_non_std_set(true); @@ -2004,6 +2008,9 @@ void atv_dmd_set_std(void) if (amlatvdemod_devp->tuner_id == AM_TUNER_R840) { if_freq = amlatvdemod_devp->if_freq; if_inv = amlatvdemod_devp->if_inv; + } else if (amlatvdemod_devp->tuner_id == AM_TUNER_R842) { + if_freq = amlatvdemod_devp->if_freq; + if_inv = amlatvdemod_devp->if_inv; } else if (amlatvdemod_devp->tuner_id == AM_TUNER_MXL661) { if_freq = amlatvdemod_devp->if_freq; if_inv = amlatvdemod_devp->if_inv; @@ -2515,7 +2522,7 @@ int amlatvdemod_reg_read(unsigned int reg, unsigned int *val) return 0; } } else if (0 == (ADC_EN_ATV_DEMOD & tvafe_adc_get_pll_flag())) { - pr_info("%s atv demod pll not init\n", __func__); + pr_dbg("%s atv demod pll not init\n", __func__); return 0; } @@ -2534,7 +2541,7 @@ int amlatvdemod_reg_write(unsigned int reg, unsigned int val) return 0; } } else if (0 == (ADC_EN_ATV_DEMOD & tvafe_adc_get_pll_flag())) { - pr_info("%s atv demod pll not init\n", __func__); + pr_dbg("%s atv demod pll not init\n", __func__); return 0; } @@ -2580,24 +2587,36 @@ int atvaudiodem_reg_write(unsigned int reg, unsigned int val) int amlatvdemod_hiu_reg_read(unsigned int reg, unsigned int *val) { - *val = readl(amlatvdemod_devp->hiu_reg_base + ((reg - 0x1000)<<2)); + if (amlatvdemod_devp->hiu_reg_base) + *val = readl(amlatvdemod_devp->hiu_reg_base + + ((reg - 0x1000) << 2)); + return 0; } int amlatvdemod_hiu_reg_write(unsigned int reg, unsigned int val) { - writel(val, (amlatvdemod_devp->hiu_reg_base + ((reg - 0x1000)<<2))); + if (amlatvdemod_devp->hiu_reg_base) + writel(val, (amlatvdemod_devp->hiu_reg_base + + ((reg - 0x1000) << 2))); + return 0; } int amlatvdemod_periphs_reg_read(unsigned int reg, unsigned int *val) { - *val = readl(amlatvdemod_devp->periphs_reg_base + ((reg - 0x1000)<<2)); + if (amlatvdemod_devp->periphs_reg_base) + *val = readl(amlatvdemod_devp->periphs_reg_base + + ((reg - 0x1000) << 2)); + return 0; } int amlatvdemod_periphs_reg_write(unsigned int reg, unsigned int val) { - writel(val, (amlatvdemod_devp->periphs_reg_base + ((reg - 0x1000)<<2))); + if (amlatvdemod_devp->periphs_reg_base) + writel(val, (amlatvdemod_devp->periphs_reg_base + + ((reg - 0x1000) << 2))); + return 0; } diff --git a/include/linux/amlogic/aml_atvdemod.h b/include/linux/amlogic/aml_atvdemod.h index b63f3ee61ae7..38f0b4b8d4fb 100644 --- a/include/linux/amlogic/aml_atvdemod.h +++ b/include/linux/amlogic/aml_atvdemod.h @@ -136,6 +136,7 @@ enum aml_tuner_type_t { AM_TUNER_MXL661 = 10, AM_TUNER_MXL608 = 11, AM_TUNER_SI2159 = 12, + AM_TUNER_R842 = 13, }; extern struct dvb_frontend *mxl661_attach(struct dvb_frontend *fe, @@ -144,6 +145,10 @@ extern struct dvb_frontend *si2151_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr); extern struct dvb_frontend *si2159_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap, u8 i2c_addr); +extern struct dvb_frontend *r840_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, u8 i2c_addr); +extern struct dvb_frontend *r842_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c_adap, u8 i2c_addr); /* For attach tuner driver end*/ #endif /* __AML_ATVDEMOD_H__ */