linux/drivers/media/dvb-frontends/a8293.c
<<
>>
Prefs
   1/*
   2 * Allegro A8293 SEC driver
   3 *
   4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
   5 *
   6 *    This program is free software; you can redistribute it and/or modify
   7 *    it under the terms of the GNU General Public License as published by
   8 *    the Free Software Foundation; either version 2 of the License, or
   9 *    (at your option) any later version.
  10 *
  11 *    This program is distributed in the hope that it will be useful,
  12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *    GNU General Public License for more details.
  15 *
  16 *    You should have received a copy of the GNU General Public License along
  17 *    with this program; if not, write to the Free Software Foundation, Inc.,
  18 *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19 */
  20
  21#include "dvb_frontend.h"
  22#include "a8293.h"
  23
  24struct a8293_priv {
  25        struct i2c_adapter *i2c;
  26        const struct a8293_config *cfg;
  27        u8 reg[2];
  28};
  29
  30static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
  31{
  32        int ret;
  33        struct i2c_msg msg[1] = {
  34                {
  35                        .addr = priv->cfg->i2c_addr,
  36                        .len = len,
  37                        .buf = val,
  38                }
  39        };
  40
  41        if (rd)
  42                msg[0].flags = I2C_M_RD;
  43        else
  44                msg[0].flags = 0;
  45
  46        ret = i2c_transfer(priv->i2c, msg, 1);
  47        if (ret == 1) {
  48                ret = 0;
  49        } else {
  50                dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
  51                                KBUILD_MODNAME, ret, rd);
  52                ret = -EREMOTEIO;
  53        }
  54
  55        return ret;
  56}
  57
  58static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
  59{
  60        return a8293_i2c(priv, val, len, 0);
  61}
  62
  63static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
  64{
  65        return a8293_i2c(priv, val, len, 1);
  66}
  67
  68static int a8293_set_voltage(struct dvb_frontend *fe,
  69        fe_sec_voltage_t fe_sec_voltage)
  70{
  71        struct a8293_priv *priv = fe->sec_priv;
  72        int ret;
  73
  74        dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
  75                        fe_sec_voltage);
  76
  77        switch (fe_sec_voltage) {
  78        case SEC_VOLTAGE_OFF:
  79                /* ENB=0 */
  80                priv->reg[0] = 0x10;
  81                break;
  82        case SEC_VOLTAGE_13:
  83                /* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
  84                priv->reg[0] = 0x31;
  85                break;
  86        case SEC_VOLTAGE_18:
  87                /* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
  88                priv->reg[0] = 0x38;
  89                break;
  90        default:
  91                ret = -EINVAL;
  92                goto err;
  93        }
  94
  95        ret = a8293_wr(priv, &priv->reg[0], 1);
  96        if (ret)
  97                goto err;
  98
  99        return ret;
 100err:
 101        dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
 102        return ret;
 103}
 104
 105static void a8293_release_sec(struct dvb_frontend *fe)
 106{
 107        a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
 108
 109        kfree(fe->sec_priv);
 110        fe->sec_priv = NULL;
 111}
 112
 113struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
 114        struct i2c_adapter *i2c, const struct a8293_config *cfg)
 115{
 116        int ret;
 117        struct a8293_priv *priv = NULL;
 118        u8 buf[2];
 119
 120        /* allocate memory for the internal priv */
 121        priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
 122        if (priv == NULL) {
 123                ret = -ENOMEM;
 124                goto err;
 125        }
 126
 127        /* setup the priv */
 128        priv->i2c = i2c;
 129        priv->cfg = cfg;
 130        fe->sec_priv = priv;
 131
 132        /* check if the SEC is there */
 133        ret = a8293_rd(priv, buf, 2);
 134        if (ret)
 135                goto err;
 136
 137        /* ENB=0 */
 138        priv->reg[0] = 0x10;
 139        ret = a8293_wr(priv, &priv->reg[0], 1);
 140        if (ret)
 141                goto err;
 142
 143        /* TMODE=0, TGATE=1 */
 144        priv->reg[1] = 0x82;
 145        ret = a8293_wr(priv, &priv->reg[1], 1);
 146        if (ret)
 147                goto err;
 148
 149        fe->ops.release_sec = a8293_release_sec;
 150
 151        /* override frontend ops */
 152        fe->ops.set_voltage = a8293_set_voltage;
 153
 154        dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
 155                        KBUILD_MODNAME);
 156
 157        return fe;
 158err:
 159        dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
 160        kfree(priv);
 161        return NULL;
 162}
 163EXPORT_SYMBOL(a8293_attach);
 164
 165MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 166MODULE_DESCRIPTION("Allegro A8293 SEC driver");
 167MODULE_LICENSE("GPL");
 168