atv_demod: pc bad value in panic after change source [1/1]
authornengwen.chen <nengwen.chen@amlogic.com>
Thu, 8 Nov 2018 11:57:53 +0000 (19:57 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 9 Nov 2018 11:52:02 +0000 (04:52 -0700)
PD#SWPL-1636

Problem:
1.pc bad value in kernel panic after change source.
2.System crash down when change source.

Solution:
optimize atv demod code.

Verify:
verified by p321

Change-Id: I655d1253950475dfb49ae1b174597797000adb73
Signed-off-by: nengwen.chen <nengwen.chen@amlogic.com>
drivers/amlogic/atv_demod/atv_demod_ops.c
drivers/amlogic/atv_demod/atv_demod_v4l2.c
drivers/amlogic/atv_demod/atv_demod_v4l2.h

index 50b556d..b620bf4 100644 (file)
@@ -65,7 +65,9 @@ void aml_fe_get_atvaudio_state(int *state)
        }
 
        /* scan mode need mute */
-       if (priv->state == ATVDEMOD_STATE_WORK && !priv->scanning) {
+       if (priv->state == ATVDEMOD_STATE_WORK
+                       && !priv->scanning
+                       && !priv->standby) {
                retrieve_vpll_carrier_lock(&vpll_lock);
                retrieve_vpll_carrier_line_lock(&line_lock);
                if ((vpll_lock == 0) && (line_lock == 0)) {
@@ -78,8 +80,9 @@ void aml_fe_get_atvaudio_state(int *state)
                }
        } else {
                *state = 0;
-               pr_audio("%s, atv is not work, atv_state: %d.\n",
-                               __func__, priv->state);
+               pr_audio("%s, ATV in state[%d], scanning[%d], standby[%d].\n",
+                               __func__, priv->state,
+                               priv->scanning, priv->standby);
        }
 
        /* If the atv signal is locked, it means there is audio data,
@@ -146,6 +149,8 @@ int atv_demod_leave_mode(struct dvb_frontend *fe)
 {
        struct atv_demod_priv *priv = fe->analog_demod_priv;
 
+       priv->state = ATVDEMOD_STATE_IDEL;
+
        if (priv->afc.disable)
                priv->afc.disable(&priv->afc);
 
@@ -167,8 +172,6 @@ int atv_demod_leave_mode(struct dvb_frontend *fe)
        amlatvdemod_devp->audmode = 0;
        amlatvdemod_devp->soundsys = 0xFF;
 
-       priv->state = ATVDEMOD_STATE_IDEL;
-
        pr_info("%s: OK.\n", __func__);
 
        return 0;
@@ -183,7 +186,7 @@ static void atv_demod_set_params(struct dvb_frontend *fe,
        struct aml_atvdemod_parameters *p = &priv->atvdemod_param;
        bool reconfig = false;
 
-       priv->standby = false;
+       priv->standby = true;
 
        /* afc tune disable,must cancel wq before set tuner freq*/
        if (priv->afc.disable)
@@ -254,6 +257,8 @@ static void atv_demod_set_params(struct dvb_frontend *fe,
                if (priv->monitor.enable)
                        priv->monitor.enable(&priv->monitor);
        }
+
+       priv->standby = false;
 }
 
 static int atv_demod_has_signal(struct dvb_frontend *fe, u16 *signal)
@@ -286,6 +291,7 @@ static void atv_demod_standby(struct dvb_frontend *fe)
        if (priv->state != ATVDEMOD_STATE_IDEL) {
                atv_demod_leave_mode(fe);
                priv->state = ATVDEMOD_STATE_SLEEP;
+               priv->standby = true;
        }
 
        pr_info("%s: OK.\n", __func__);
@@ -355,8 +361,10 @@ static int atv_demod_set_config(struct dvb_frontend *fe, void *priv_cfg)
 
        case AML_ATVDEMOD_RESUME:
                if (priv->state == ATVDEMOD_STATE_SLEEP) {
-                       if (!atv_demod_enter_mode(fe))
+                       if (!atv_demod_enter_mode(fe)) {
                                priv->state = ATVDEMOD_STATE_WORK;
+                               priv->standby = false;
+                       }
                }
                break;
 
index 76413a9..beaad44 100644 (file)
@@ -331,6 +331,14 @@ static int v4l2_frontend_start(struct v4l2_frontend *v4l2_fe)
 }
 
 
+static int v4l2_frontend_check_mode(struct v4l2_frontend *v4l2_fe)
+{
+       if (v4l2_fe->mode != V4L2_TUNER_ANALOG_TV)
+               return -EINVAL;
+
+       return 0;
+}
+
 static int v4l2_set_frontend(struct v4l2_frontend *v4l2_fe,
                struct v4l2_analog_parameters *params)
 {
@@ -343,6 +351,9 @@ static int v4l2_set_frontend(struct v4l2_frontend *v4l2_fe,
 
        pr_dbg("%s.\n", __func__);
 
+       if (v4l2_frontend_check_mode(v4l2_fe) < 0)
+               return -EINVAL;
+
        freq_min = fe->ops.tuner_ops.info.frequency_min;
        freq_max = fe->ops.tuner_ops.info.frequency_max;
 
@@ -419,10 +430,13 @@ static int v4l2_frontend_set_mode(struct v4l2_frontend *v4l2_fe,
 
        analog_ops = &v4l2_fe->fe.ops.analog_ops;
 
-       if (params)
+       if (params) {
                priv_cfg = AML_ATVDEMOD_INIT;
-       else
+               v4l2_fe->mode = V4L2_TUNER_ANALOG_TV;
+       } else {
                priv_cfg = AML_ATVDEMOD_UNINIT;
+               v4l2_fe->mode = V4L2_TUNER_RF;
+       }
 
        if (analog_ops && analog_ops->set_config)
                ret = analog_ops->set_config(&v4l2_fe->fe, &priv_cfg);
index 0b2c9cd..0683c94 100644 (file)
@@ -199,6 +199,8 @@ struct v4l2_frontend {
        unsigned int tuner_id;
        struct i2c_client i2c;
 
+       enum v4l2_tuner_type mode;
+
        void *frontend_priv;
        void *tuner_priv;
        void *analog_demod_priv;