]> err.no Git - linux-2.6/blobdiff - drivers/media/dvb/frontends/au8522.c
V4L/DVB (7920): s5h1409.c shouldn't #include "dvb-pll.h"
[linux-2.6] / drivers / media / dvb / frontends / au8522.c
index fa3e6abdfa6e6b532fb64a54c5f5f2f927759896..f7b71657f0f6324f57891d470faf1d2a4f30275f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include "dvb_frontend.h"
-#include "dvb-pll.h"
 #include "au8522.h"
 
 struct au8522_state {
@@ -43,8 +42,12 @@ struct au8522_state {
 
 };
 
-static int debug = 0;
-#define dprintk        if (debug) printk
+static int debug;
+
+#define dprintk(arg...) do {           \
+       if (debug)                      \
+                printk(arg);           \
+       } while (0)
 
 /* 16 bit registers, 8 bit values */
 static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
@@ -96,11 +99,13 @@ static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
                return au8522_writereg(state, 0x106, 0);
 }
 
-/* VSB SNR lookup table */
-static struct {
+struct mse2snr_tab {
        u16 val;
        u16 data;
-} vsb_mse2snr_tab[] = {
+};
+
+/* VSB SNR lookup table */
+static struct mse2snr_tab vsb_mse2snr_tab[] = {
        {   0, 270 },
        {   2, 250 },
        {   3, 240 },
@@ -134,10 +139,7 @@ static struct {
 };
 
 /* QAM64 SNR lookup table */
-static struct {
-       u16 val;
-       u16 data;
-} qam64_mse2snr_tab[] = {
+static struct mse2snr_tab qam64_mse2snr_tab[] = {
        {  15,   0 },
        {  16, 290 },
        {  17, 288 },
@@ -218,10 +220,7 @@ static struct {
 };
 
 /* QAM256 SNR lookup table */
-static struct {
-       u16 val;
-       u16 data;
-} qam256_mse2snr_tab[] = {
+static struct mse2snr_tab qam256_mse2snr_tab[] = {
        {  16,   0 },
        {  17, 400 },
        {  18, 398 },
@@ -288,46 +287,15 @@ static struct {
        { 256, 280 },
 };
 
-static int au8522_vsb_mse2snr_lookup(int mse, u16 *snr)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(vsb_mse2snr_tab); i++) {
-               if (mse < vsb_mse2snr_tab[i].val) {
-                       *snr = vsb_mse2snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       dprintk("%s() snr=%d\n", __func__, *snr);
-       return ret;
-}
-
-static int au8522_qam64_mse2snr_lookup(int mse, u16 *snr)
-{
-       int i, ret = -EINVAL;
-       dprintk("%s()\n", __func__);
-
-       for (i = 0; i < ARRAY_SIZE(qam64_mse2snr_tab); i++) {
-               if (mse < qam64_mse2snr_tab[i].val) {
-                       *snr = qam64_mse2snr_tab[i].data;
-                       ret = 0;
-                       break;
-               }
-       }
-       dprintk("%s() snr=%d\n", __func__, *snr);
-       return ret;
-}
-
-static int au8522_qam256_mse2snr_lookup(int mse, u16 *snr)
+static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
+                                u16 *snr)
 {
        int i, ret = -EINVAL;
        dprintk("%s()\n", __func__);
 
-       for (i = 0; i < ARRAY_SIZE(qam256_mse2snr_tab); i++) {
-               if (mse < qam256_mse2snr_tab[i].val) {
-                       *snr = qam256_mse2snr_tab[i].data;
+       for (i = 0; i < sz; i++) {
+               if (mse < tab[i].val) {
+                       *snr = tab[i].data;
                        ret = 0;
                        break;
                }
@@ -463,7 +431,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
 
        dprintk("%s(0x%08x)\n", __func__, m);
 
-       switch(m) {
+       switch (m) {
        case VSB_8:
                dprintk("%s() VSB_8\n", __func__);
                for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
@@ -494,10 +462,13 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
                               struct dvb_frontend_parameters *p)
 {
        struct au8522_state *state = fe->demodulator_priv;
+       int ret = -EINVAL;
 
        dprintk("%s(frequency=%d)\n", __func__, p->frequency);
 
-       state->current_frequency = p->frequency;
+       if ((state->current_frequency == p->frequency) &&
+           (state->current_modulation == p->u.vsb.modulation))
+               return 0;
 
        au8522_enable_modulation(fe, p->u.vsb.modulation);
 
@@ -505,11 +476,18 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
        msleep(100);
 
        if (fe->ops.tuner_ops.set_params) {
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe, p);
-               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 1);
+               ret = fe->ops.tuner_ops.set_params(fe, p);
+               if (fe->ops.i2c_gate_ctrl)
+                       fe->ops.i2c_gate_ctrl(fe, 0);
        }
 
+       if (ret < 0)
+               return ret;
+
+       state->current_frequency = p->frequency;
+
        return 0;
 }
 
@@ -527,6 +505,16 @@ static int au8522_init(struct dvb_frontend *fe)
        return 0;
 }
 
+static int au8522_sleep(struct dvb_frontend *fe)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       dprintk("%s()\n", __func__);
+
+       state->current_frequency = 0;
+
+       return 0;
+}
+
 static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
        struct au8522_state *state = fe->demodulator_priv;
@@ -537,12 +525,9 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
 
        if (state->current_modulation == VSB_8) {
                dprintk("%s() Checking VSB_8\n", __func__);
-               //au8522_writereg(state, 0x80a4, 0x20);
                reg = au8522_readreg(state, 0x4088);
-               if (reg & 0x01)
-                       *status |= FE_HAS_VITERBI;
-               if (reg & 0x02)
-                       *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+               if ((reg & 0x03) == 0x03)
+                       *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
        } else {
                dprintk("%s() Checking QAM\n", __func__);
                reg = au8522_readreg(state, 0x4541);
@@ -552,7 +537,7 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
                        *status |= FE_HAS_LOCK | FE_HAS_SYNC;
        }
 
-       switch(state->config->status_mode) {
+       switch (state->config->status_mode) {
        case AU8522_DEMODLOCKING:
                dprintk("%s() DEMODLOCKING\n", __func__);
                if (*status & FE_HAS_VITERBI)
@@ -588,14 +573,20 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
        dprintk("%s()\n", __func__);
 
        if (state->current_modulation == QAM_256)
-               ret = au8522_qam256_mse2snr_lookup(
-                       au8522_readreg(state, 0x4522), snr);
+               ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
+                                           ARRAY_SIZE(qam256_mse2snr_tab),
+                                           au8522_readreg(state, 0x4522),
+                                           snr);
        else if (state->current_modulation == QAM_64)
-               ret = au8522_qam64_mse2snr_lookup(
-                       au8522_readreg(state, 0x4522), snr);
+               ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
+                                           ARRAY_SIZE(qam64_mse2snr_tab),
+                                           au8522_readreg(state, 0x4522),
+                                           snr);
        else /* VSB_8 */
-               ret = au8522_vsb_mse2snr_lookup(
-                       au8522_readreg(state, 0x4311), snr);
+               ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
+                                           ARRAY_SIZE(vsb_mse2snr_tab),
+                                           au8522_readreg(state, 0x4311),
+                                           snr);
 
        return ret;
 }
@@ -682,6 +673,7 @@ error:
        kfree(state);
        return NULL;
 }
+EXPORT_SYMBOL(au8522_attach);
 
 static struct dvb_frontend_ops au8522_ops = {
 
@@ -695,6 +687,7 @@ static struct dvb_frontend_ops au8522_ops = {
        },
 
        .init                 = au8522_init,
+       .sleep                = au8522_sleep,
        .i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
        .set_frontend         = au8522_set_frontend,
        .get_frontend         = au8522_get_frontend,
@@ -713,10 +706,3 @@ MODULE_PARM_DESC(debug, "Enable verbose debug messages");
 MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
 MODULE_AUTHOR("Steven Toth");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(au8522_attach);
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */