[media] mt2060: implement sleep
authorAntti Palosaari <crope@iki.fi>
Fri, 9 Dec 2016 17:11:09 +0000 (15:11 -0200)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Fri, 3 Feb 2017 08:55:46 +0000 (06:55 -0200)
I saw from ZyDAS ZD1301 sniffs it sets chip sleeping by using
REG_MISC_CTRL. That has very huge effect for power management, around
0.9W. Sleep is still disabled for all the old hardware just to avoid
possible regression as meaning of register bits are unknown.

I tested it also with some other devices and it seems to be working,
but I still consider it to be too risky to change it default.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/tuners/mt2060.c
drivers/media/tuners/mt2060_priv.h

index 14f5935f8898b9542a1f2070c8f507c4bc2152ce..2e487f9a2cc3fb678aa173b93a9bb141cc23ba69 100644 (file)
@@ -313,9 +313,16 @@ static int mt2060_init(struct dvb_frontend *fe)
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
 
+       if (priv->sleep) {
+               ret = mt2060_writereg(priv, REG_MISC_CTRL, 0x20);
+               if (ret)
+                       goto err_i2c_gate_ctrl;
+       }
+
        ret = mt2060_writereg(priv, REG_VGAG,
                              (priv->cfg->clock_out << 6) | 0x33);
 
+err_i2c_gate_ctrl:
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
 
@@ -332,7 +339,13 @@ static int mt2060_sleep(struct dvb_frontend *fe)
 
        ret = mt2060_writereg(priv, REG_VGAG,
                              (priv->cfg->clock_out << 6) | 0x30);
+       if (ret)
+               goto err_i2c_gate_ctrl;
+
+       if (priv->sleep)
+               ret = mt2060_writereg(priv, REG_MISC_CTRL, 0xe8);
 
+err_i2c_gate_ctrl:
        if (fe->ops.i2c_gate_ctrl)
                fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
 
@@ -435,6 +448,7 @@ static int mt2060_probe(struct i2c_client *client,
        dev->if1_freq = pdata->if1 ? pdata->if1 : 1220;
        dev->client = client;
        dev->i2c_max_regs = pdata->i2c_write_max ? pdata->i2c_write_max - 1 : ~0;
+       dev->sleep = true;
 
        ret = mt2060_readreg(dev, REG_PART_REV, &chip_id);
        if (ret) {
@@ -449,14 +463,21 @@ static int mt2060_probe(struct i2c_client *client,
                goto err;
        }
 
+       /* Power on, calibrate, sleep */
+       ret = mt2060_writereg(dev, REG_MISC_CTRL, 0x20);
+       if (ret)
+               goto err;
+       mt2060_calibrate(dev);
+       ret = mt2060_writereg(dev, REG_MISC_CTRL, 0xe8);
+       if (ret)
+               goto err;
+
        dev_info(&client->dev, "Microtune MT2060 successfully identified\n");
        memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(fe->ops.tuner_ops));
        fe->ops.tuner_ops.release = NULL;
        fe->tuner_priv = dev;
        i2c_set_clientdata(client, dev);
 
-       mt2060_calibrate(dev);
-
        return 0;
 err:
        dev_dbg(&client->dev, "failed=%d\n", ret);
index cc738aa82fe4edca14ec53ac28c256f5dbb1daa8..a6c931c1a5a7bb831c7ed3631a253c9cce7c8d3d 100644 (file)
@@ -98,6 +98,14 @@ struct mt2060_priv {
        u32 frequency;
        u16 if1_freq;
        u8  fmfreq;
+
+       /*
+        * Use REG_MISC_CTRL register for sleep. That drops sleep power usage
+        * about 0.9W (huge!). Register bit meanings are unknown, so let it be
+        * disabled by default to avoid possible regression. Convert driver to
+        * i2c model in order to enable it.
+        */
+       bool sleep;
 };
 
 #endif