linux/drivers/media/tuners/tuner_it913x.c
<<
>>
Prefs
   1/*
   2 * ITE Tech IT9137 silicon tuner driver
   3 *
   4 *  Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
   5 *  IT9137 Copyright (C) ITE Tech Inc.
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License as published by
   9 *  the Free Software Foundation; either version 2 of the License, or
  10 *  (at your option) any later version.
  11 *
  12 *  This program is distributed in the hope that it will be useful,
  13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
  21 */
  22
  23#include "tuner_it913x_priv.h"
  24
  25struct it913x_state {
  26        struct i2c_adapter *i2c_adap;
  27        u8 i2c_addr;
  28        u8 chip_ver;
  29        u8 tuner_type;
  30        u8 firmware_ver;
  31        u16 tun_xtal;
  32        u8 tun_fdiv;
  33        u8 tun_clk_mode;
  34        u32 tun_fn_min;
  35};
  36
  37/* read multiple registers */
  38static int it913x_rd_regs(struct it913x_state *state,
  39                u32 reg, u8 *data, u8 count)
  40{
  41        int ret;
  42        u8 b[3];
  43        struct i2c_msg msg[2] = {
  44                { .addr = state->i2c_addr, .flags = 0,
  45                        .buf = b, .len = sizeof(b) },
  46                { .addr = state->i2c_addr, .flags = I2C_M_RD,
  47                        .buf = data, .len = count }
  48        };
  49        b[0] = (u8)(reg >> 16) & 0xff;
  50        b[1] = (u8)(reg >> 8) & 0xff;
  51        b[2] = (u8) reg & 0xff;
  52        b[0] |= 0x80; /* All reads from demodulator */
  53
  54        ret = i2c_transfer(state->i2c_adap, msg, 2);
  55
  56        return ret;
  57}
  58
  59/* read single register */
  60static int it913x_rd_reg(struct it913x_state *state, u32 reg)
  61{
  62        int ret;
  63        u8 b[1];
  64        ret = it913x_rd_regs(state, reg, &b[0], sizeof(b));
  65        return (ret < 0) ? -ENODEV : b[0];
  66}
  67
  68/* write multiple registers */
  69static int it913x_wr_regs(struct it913x_state *state,
  70                u8 pro, u32 reg, u8 buf[], u8 count)
  71{
  72        u8 b[256];
  73        struct i2c_msg msg[1] = {
  74                { .addr = state->i2c_addr, .flags = 0,
  75                  .buf = b, .len = 3 + count }
  76        };
  77        int ret;
  78        b[0] = (u8)(reg >> 16) & 0xff;
  79        b[1] = (u8)(reg >> 8) & 0xff;
  80        b[2] = (u8) reg & 0xff;
  81        memcpy(&b[3], buf, count);
  82
  83        if (pro == PRO_DMOD)
  84                b[0] |= 0x80;
  85
  86        ret = i2c_transfer(state->i2c_adap, msg, 1);
  87
  88        if (ret < 0)
  89                return -EIO;
  90
  91        return 0;
  92}
  93
  94/* write single register */
  95static int it913x_wr_reg(struct it913x_state *state,
  96                u8 pro, u32 reg, u32 data)
  97{
  98        int ret;
  99        u8 b[4];
 100        u8 s;
 101
 102        b[0] = data >> 24;
 103        b[1] = (data >> 16) & 0xff;
 104        b[2] = (data >> 8) & 0xff;
 105        b[3] = data & 0xff;
 106        /* expand write as needed */
 107        if (data < 0x100)
 108                s = 3;
 109        else if (data < 0x1000)
 110                s = 2;
 111        else if (data < 0x100000)
 112                s = 1;
 113        else
 114                s = 0;
 115
 116        ret = it913x_wr_regs(state, pro, reg, &b[s], sizeof(b) - s);
 117
 118        return ret;
 119}
 120
 121static int it913x_script_loader(struct it913x_state *state,
 122                struct it913xset *loadscript)
 123{
 124        int ret, i;
 125        if (loadscript == NULL)
 126                return -EINVAL;
 127
 128        for (i = 0; i < 1000; ++i) {
 129                if (loadscript[i].pro == 0xff)
 130                        break;
 131                ret = it913x_wr_regs(state, loadscript[i].pro,
 132                        loadscript[i].address,
 133                        loadscript[i].reg, loadscript[i].count);
 134                if (ret < 0)
 135                        return -ENODEV;
 136        }
 137        return 0;
 138}
 139
 140static int it913x_init(struct dvb_frontend *fe)
 141{
 142        struct it913x_state *state = fe->tuner_priv;
 143        int ret, i, reg;
 144        u8 val, nv_val;
 145        u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};
 146        u8 b[2];
 147
 148        reg = it913x_rd_reg(state, 0xec86);
 149        switch (reg) {
 150        case 0:
 151                state->tun_clk_mode = reg;
 152                state->tun_xtal = 2000;
 153                state->tun_fdiv = 3;
 154                val = 16;
 155                break;
 156        case -ENODEV:
 157                return -ENODEV;
 158        case 1:
 159        default:
 160                state->tun_clk_mode = reg;
 161                state->tun_xtal = 640;
 162                state->tun_fdiv = 1;
 163                val = 6;
 164                break;
 165        }
 166
 167        reg = it913x_rd_reg(state, 0xed03);
 168
 169        if (reg < 0)
 170                return -ENODEV;
 171        else if (reg < ARRAY_SIZE(nv))
 172                nv_val = nv[reg];
 173        else
 174                nv_val = 2;
 175
 176        for (i = 0; i < 50; i++) {
 177                ret = it913x_rd_regs(state, 0xed23, &b[0], sizeof(b));
 178                reg = (b[1] << 8) + b[0];
 179                if (reg > 0)
 180                        break;
 181                if (ret < 0)
 182                        return -ENODEV;
 183                udelay(2000);
 184        }
 185        state->tun_fn_min = state->tun_xtal * reg;
 186        state->tun_fn_min /= (state->tun_fdiv * nv_val);
 187        dev_dbg(&state->i2c_adap->dev, "%s: Tuner fn_min %d\n", __func__,
 188                        state->tun_fn_min);
 189
 190        if (state->chip_ver > 1)
 191                msleep(50);
 192        else {
 193                for (i = 0; i < 50; i++) {
 194                        reg = it913x_rd_reg(state, 0xec82);
 195                        if (reg > 0)
 196                                break;
 197                        if (reg < 0)
 198                                return -ENODEV;
 199                        udelay(2000);
 200                }
 201        }
 202
 203        /* Power Up Tuner - common all versions */
 204        ret = it913x_wr_reg(state, PRO_DMOD, 0xec40, 0x1);
 205        ret |= it913x_wr_reg(state, PRO_DMOD, 0xfba8, 0x0);
 206        ret |= it913x_wr_reg(state, PRO_DMOD, 0xec57, 0x0);
 207        ret |= it913x_wr_reg(state, PRO_DMOD, 0xec58, 0x0);
 208
 209        return it913x_wr_reg(state, PRO_DMOD, 0xed81, val);
 210}
 211
 212static int it9137_set_params(struct dvb_frontend *fe)
 213{
 214        struct it913x_state *state = fe->tuner_priv;
 215        struct it913xset *set_tuner = set_it9137_template;
 216        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 217        u32 bandwidth = p->bandwidth_hz;
 218        u32 frequency_m = p->frequency;
 219        int ret, reg;
 220        u32 frequency = frequency_m / 1000;
 221        u32 freq, temp_f, tmp;
 222        u16 iqik_m_cal;
 223        u16 n_div;
 224        u8 n;
 225        u8 l_band;
 226        u8 lna_band;
 227        u8 bw;
 228
 229        if (state->firmware_ver == 1)
 230                set_tuner = set_it9135_template;
 231        else
 232                set_tuner = set_it9137_template;
 233
 234        dev_dbg(&state->i2c_adap->dev, "%s: Tuner Frequency %d Bandwidth %d\n",
 235                        __func__, frequency, bandwidth);
 236
 237        if (frequency >= 51000 && frequency <= 440000) {
 238                l_band = 0;
 239                lna_band = 0;
 240        } else if (frequency > 440000 && frequency <= 484000) {
 241                l_band = 1;
 242                lna_band = 1;
 243        } else if (frequency > 484000 && frequency <= 533000) {
 244                l_band = 1;
 245                lna_band = 2;
 246        } else if (frequency > 533000 && frequency <= 587000) {
 247                l_band = 1;
 248                lna_band = 3;
 249        } else if (frequency > 587000 && frequency <= 645000) {
 250                l_band = 1;
 251                lna_band = 4;
 252        } else if (frequency > 645000 && frequency <= 710000) {
 253                l_band = 1;
 254                lna_band = 5;
 255        } else if (frequency > 710000 && frequency <= 782000) {
 256                l_band = 1;
 257                lna_band = 6;
 258        } else if (frequency > 782000 && frequency <= 860000) {
 259                l_band = 1;
 260                lna_band = 7;
 261        } else if (frequency > 1450000 && frequency <= 1492000) {
 262                l_band = 1;
 263                lna_band = 0;
 264        } else if (frequency > 1660000 && frequency <= 1685000) {
 265                l_band = 1;
 266                lna_band = 1;
 267        } else
 268                return -EINVAL;
 269        set_tuner[0].reg[0] = lna_band;
 270
 271        switch (bandwidth) {
 272        case 5000000:
 273                bw = 0;
 274                break;
 275        case 6000000:
 276                bw = 2;
 277                break;
 278        case 7000000:
 279                bw = 4;
 280                break;
 281        default:
 282        case 8000000:
 283                bw = 6;
 284                break;
 285        }
 286
 287        set_tuner[1].reg[0] = bw;
 288        set_tuner[2].reg[0] = 0xa0 | (l_band << 3);
 289
 290        if (frequency > 53000 && frequency <= 74000) {
 291                n_div = 48;
 292                n = 0;
 293        } else if (frequency > 74000 && frequency <= 111000) {
 294                n_div = 32;
 295                n = 1;
 296        } else if (frequency > 111000 && frequency <= 148000) {
 297                n_div = 24;
 298                n = 2;
 299        } else if (frequency > 148000 && frequency <= 222000) {
 300                n_div = 16;
 301                n = 3;
 302        } else if (frequency > 222000 && frequency <= 296000) {
 303                n_div = 12;
 304                n = 4;
 305        } else if (frequency > 296000 && frequency <= 445000) {
 306                n_div = 8;
 307                n = 5;
 308        } else if (frequency > 445000 && frequency <= state->tun_fn_min) {
 309                n_div = 6;
 310                n = 6;
 311        } else if (frequency > state->tun_fn_min && frequency <= 950000) {
 312                n_div = 4;
 313                n = 7;
 314        } else if (frequency > 1450000 && frequency <= 1680000) {
 315                n_div = 2;
 316                n = 0;
 317        } else
 318                return -EINVAL;
 319
 320        reg = it913x_rd_reg(state, 0xed81);
 321        iqik_m_cal = (u16)reg * n_div;
 322
 323        if (reg < 0x20) {
 324                if (state->tun_clk_mode == 0)
 325                        iqik_m_cal = (iqik_m_cal * 9) >> 5;
 326                else
 327                        iqik_m_cal >>= 1;
 328        } else {
 329                iqik_m_cal = 0x40 - iqik_m_cal;
 330                if (state->tun_clk_mode == 0)
 331                        iqik_m_cal = ~((iqik_m_cal * 9) >> 5);
 332                else
 333                        iqik_m_cal = ~(iqik_m_cal >> 1);
 334        }
 335
 336        temp_f = frequency * (u32)n_div * (u32)state->tun_fdiv;
 337        freq = temp_f / state->tun_xtal;
 338        tmp = freq * state->tun_xtal;
 339
 340        if ((temp_f - tmp) >= (state->tun_xtal >> 1))
 341                freq++;
 342
 343        freq += (u32) n << 13;
 344        /* Frequency OMEGA_IQIK_M_CAL_MID*/
 345        temp_f = freq + (u32)iqik_m_cal;
 346
 347        set_tuner[3].reg[0] =  temp_f & 0xff;
 348        set_tuner[4].reg[0] =  (temp_f >> 8) & 0xff;
 349
 350        dev_dbg(&state->i2c_adap->dev, "%s: High Frequency = %04x\n",
 351                        __func__, temp_f);
 352
 353        /* Lower frequency */
 354        set_tuner[5].reg[0] =  freq & 0xff;
 355        set_tuner[6].reg[0] =  (freq >> 8) & 0xff;
 356
 357        dev_dbg(&state->i2c_adap->dev, "%s: low Frequency = %04x\n",
 358                        __func__, freq);
 359
 360        ret = it913x_script_loader(state, set_tuner);
 361
 362        return (ret < 0) ? -ENODEV : 0;
 363}
 364
 365/* Power sequence */
 366/* Power Up     Tuner on -> Frontend suspend off -> Tuner clk on */
 367/* Power Down   Frontend suspend on -> Tuner clk off -> Tuner off */
 368
 369static int it913x_sleep(struct dvb_frontend *fe)
 370{
 371        struct it913x_state *state = fe->tuner_priv;
 372        return it913x_script_loader(state, it9137_tuner_off);
 373}
 374
 375static int it913x_release(struct dvb_frontend *fe)
 376{
 377        kfree(fe->tuner_priv);
 378        return 0;
 379}
 380
 381static const struct dvb_tuner_ops it913x_tuner_ops = {
 382        .info = {
 383                .name           = "ITE Tech IT913X",
 384                .frequency_min  = 174000000,
 385                .frequency_max  = 862000000,
 386        },
 387
 388        .release = it913x_release,
 389
 390        .init = it913x_init,
 391        .sleep = it913x_sleep,
 392        .set_params = it9137_set_params,
 393};
 394
 395struct dvb_frontend *it913x_attach(struct dvb_frontend *fe,
 396                struct i2c_adapter *i2c_adap, u8 i2c_addr, u8 config)
 397{
 398        struct it913x_state *state = NULL;
 399
 400        /* allocate memory for the internal state */
 401        state = kzalloc(sizeof(struct it913x_state), GFP_KERNEL);
 402        if (state == NULL)
 403                return NULL;
 404
 405        state->i2c_adap = i2c_adap;
 406        state->i2c_addr = i2c_addr;
 407
 408        switch (config) {
 409        case AF9033_TUNER_IT9135_38:
 410        case AF9033_TUNER_IT9135_51:
 411        case AF9033_TUNER_IT9135_52:
 412                state->chip_ver = 0x01;
 413                break;
 414        case AF9033_TUNER_IT9135_60:
 415        case AF9033_TUNER_IT9135_61:
 416        case AF9033_TUNER_IT9135_62:
 417                state->chip_ver = 0x02;
 418                break;
 419        default:
 420                dev_dbg(&i2c_adap->dev,
 421                                "%s: invalid config=%02x\n", __func__, config);
 422                goto error;
 423        }
 424
 425        state->tuner_type = config;
 426        state->firmware_ver = 1;
 427
 428        fe->tuner_priv = state;
 429        memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,
 430                        sizeof(struct dvb_tuner_ops));
 431
 432        dev_info(&i2c_adap->dev,
 433                        "%s: ITE Tech IT913X successfully attached\n",
 434                        KBUILD_MODNAME);
 435        dev_dbg(&i2c_adap->dev, "%s: config=%02x chip_ver=%02x\n",
 436                        __func__, config, state->chip_ver);
 437
 438        return fe;
 439error:
 440        kfree(state);
 441        return NULL;
 442}
 443EXPORT_SYMBOL(it913x_attach);
 444
 445MODULE_DESCRIPTION("ITE Tech IT913X silicon tuner driver");
 446MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 447MODULE_LICENSE("GPL");
 448