linux/drivers/media/dvb-frontends/dibx000_common.c
<<
>>
Prefs
   1#include <linux/i2c.h>
   2#include <linux/mutex.h>
   3#include <linux/module.h>
   4
   5#include "dibx000_common.h"
   6
   7static int debug;
   8module_param(debug, int, 0644);
   9MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  10
  11#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
  12
  13static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
  14{
  15        int ret;
  16
  17        if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
  18                dprintk("could not acquire lock");
  19                return -EINVAL;
  20        }
  21
  22        mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
  23        mst->i2c_write_buffer[1] = reg & 0xff;
  24        mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
  25        mst->i2c_write_buffer[3] = val & 0xff;
  26
  27        memset(mst->msg, 0, sizeof(struct i2c_msg));
  28        mst->msg[0].addr = mst->i2c_addr;
  29        mst->msg[0].flags = 0;
  30        mst->msg[0].buf = mst->i2c_write_buffer;
  31        mst->msg[0].len = 4;
  32
  33        ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
  34        mutex_unlock(&mst->i2c_buffer_lock);
  35
  36        return ret;
  37}
  38
  39static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
  40{
  41        u16 ret;
  42
  43        if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
  44                dprintk("could not acquire lock");
  45                return 0;
  46        }
  47
  48        mst->i2c_write_buffer[0] = reg >> 8;
  49        mst->i2c_write_buffer[1] = reg & 0xff;
  50
  51        memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
  52        mst->msg[0].addr = mst->i2c_addr;
  53        mst->msg[0].flags = 0;
  54        mst->msg[0].buf = mst->i2c_write_buffer;
  55        mst->msg[0].len = 2;
  56        mst->msg[1].addr = mst->i2c_addr;
  57        mst->msg[1].flags = I2C_M_RD;
  58        mst->msg[1].buf = mst->i2c_read_buffer;
  59        mst->msg[1].len = 2;
  60
  61        if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
  62                dprintk("i2c read error on %d", reg);
  63
  64        ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
  65        mutex_unlock(&mst->i2c_buffer_lock);
  66
  67        return ret;
  68}
  69
  70static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
  71{
  72        int i = 100;
  73        u16 status;
  74
  75        while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
  76                ;
  77
  78        /* i2c timed out */
  79        if (i == 0)
  80                return -EREMOTEIO;
  81
  82        /* no acknowledge */
  83        if ((status & 0x0080) == 0)
  84                return -EREMOTEIO;
  85
  86        return 0;
  87}
  88
  89static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
  90{
  91        u16 data;
  92        u16 da;
  93        u16 i;
  94        u16 txlen = msg->len, len;
  95        const u8 *b = msg->buf;
  96
  97        while (txlen) {
  98                dibx000_read_word(mst, mst->base_reg + 2);
  99
 100                len = txlen > 8 ? 8 : txlen;
 101                for (i = 0; i < len; i += 2) {
 102                        data = *b++ << 8;
 103                        if (i+1 < len)
 104                                data |= *b++;
 105                        dibx000_write_word(mst, mst->base_reg, data);
 106                }
 107                da = (((u8) (msg->addr))  << 9) |
 108                        (1           << 8) |
 109                        (1           << 7) |
 110                        (0           << 6) |
 111                        (0           << 5) |
 112                        ((len & 0x7) << 2) |
 113                        (0           << 1) |
 114                        (0           << 0);
 115
 116                if (txlen == msg->len)
 117                        da |= 1 << 5; /* start */
 118
 119                if (txlen-len == 0 && stop)
 120                        da |= 1 << 6; /* stop */
 121
 122                dibx000_write_word(mst, mst->base_reg+1, da);
 123
 124                if (dibx000_is_i2c_done(mst) != 0)
 125                        return -EREMOTEIO;
 126                txlen -= len;
 127        }
 128
 129        return 0;
 130}
 131
 132static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
 133{
 134        u16 da;
 135        u8 *b = msg->buf;
 136        u16 rxlen = msg->len, len;
 137
 138        while (rxlen) {
 139                len = rxlen > 8 ? 8 : rxlen;
 140                da = (((u8) (msg->addr)) << 9) |
 141                        (1           << 8) |
 142                        (1           << 7) |
 143                        (0           << 6) |
 144                        (0           << 5) |
 145                        ((len & 0x7) << 2) |
 146                        (1           << 1) |
 147                        (0           << 0);
 148
 149                if (rxlen == msg->len)
 150                        da |= 1 << 5; /* start */
 151
 152                if (rxlen-len == 0)
 153                        da |= 1 << 6; /* stop */
 154                dibx000_write_word(mst, mst->base_reg+1, da);
 155
 156                if (dibx000_is_i2c_done(mst) != 0)
 157                        return -EREMOTEIO;
 158
 159                rxlen -= len;
 160
 161                while (len) {
 162                        da = dibx000_read_word(mst, mst->base_reg);
 163                        *b++ = (da >> 8) & 0xff;
 164                        len--;
 165                        if (len >= 1) {
 166                                *b++ =  da   & 0xff;
 167                                len--;
 168                        }
 169                }
 170        }
 171
 172        return 0;
 173}
 174
 175int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
 176{
 177        struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 178
 179        if (mst->device_rev < DIB7000MC && speed < 235)
 180                speed = 235;
 181        return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
 182
 183}
 184EXPORT_SYMBOL(dibx000_i2c_set_speed);
 185
 186static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
 187{
 188        return I2C_FUNC_I2C;
 189}
 190
 191static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
 192                                        enum dibx000_i2c_interface intf)
 193{
 194        if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
 195                dprintk("selecting interface: %d", intf);
 196                mst->selected_interface = intf;
 197                return dibx000_write_word(mst, mst->base_reg + 4, intf);
 198        }
 199        return 0;
 200}
 201
 202static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
 203{
 204        struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 205        int msg_index;
 206        int ret = 0;
 207
 208        dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
 209        for (msg_index = 0; msg_index < num; msg_index++) {
 210                if (msg[msg_index].flags & I2C_M_RD) {
 211                        ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
 212                        if (ret != 0)
 213                                return 0;
 214                } else {
 215                        ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
 216                        if (ret != 0)
 217                                return 0;
 218                }
 219        }
 220
 221        return num;
 222}
 223
 224static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
 225{
 226        struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 227        int msg_index;
 228        int ret = 0;
 229
 230        dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
 231        for (msg_index = 0; msg_index < num; msg_index++) {
 232                if (msg[msg_index].flags & I2C_M_RD) {
 233                        ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
 234                        if (ret != 0)
 235                                return 0;
 236                } else {
 237                        ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
 238                        if (ret != 0)
 239                                return 0;
 240                }
 241        }
 242
 243        return num;
 244}
 245
 246static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
 247        .master_xfer = dibx000_i2c_master_xfer_gpio12,
 248        .functionality = dibx000_i2c_func,
 249};
 250
 251static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
 252        .master_xfer = dibx000_i2c_master_xfer_gpio34,
 253        .functionality = dibx000_i2c_func,
 254};
 255
 256static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
 257                                 u8 addr, int onoff)
 258{
 259        u16 val;
 260
 261
 262        if (onoff)
 263                val = addr << 8;        // bit 7 = use master or not, if 0, the gate is open
 264        else
 265                val = 1 << 7;
 266
 267        if (mst->device_rev > DIB7000)
 268                val <<= 1;
 269
 270        tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
 271        tx[1] = ((mst->base_reg + 1) & 0xff);
 272        tx[2] = val >> 8;
 273        tx[3] = val & 0xff;
 274
 275        return 0;
 276}
 277
 278static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
 279                                        struct i2c_msg msg[], int num)
 280{
 281        struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 282        int ret;
 283
 284        if (num > 32) {
 285                dprintk("%s: too much I2C message to be transmitted (%i).\
 286                                Maximum is 32", __func__, num);
 287                return -ENOMEM;
 288        }
 289
 290        dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
 291
 292        if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
 293                dprintk("could not acquire lock");
 294                return -EINVAL;
 295        }
 296
 297        memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
 298
 299        /* open the gate */
 300        dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
 301        mst->msg[0].addr = mst->i2c_addr;
 302        mst->msg[0].buf = &mst->i2c_write_buffer[0];
 303        mst->msg[0].len = 4;
 304
 305        memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
 306
 307        /* close the gate */
 308        dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
 309        mst->msg[num + 1].addr = mst->i2c_addr;
 310        mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
 311        mst->msg[num + 1].len = 4;
 312
 313        ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
 314                        num : -EIO);
 315
 316        mutex_unlock(&mst->i2c_buffer_lock);
 317        return ret;
 318}
 319
 320static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
 321        .master_xfer = dibx000_i2c_gated_gpio67_xfer,
 322        .functionality = dibx000_i2c_func,
 323};
 324
 325static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
 326                                        struct i2c_msg msg[], int num)
 327{
 328        struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 329        int ret;
 330
 331        if (num > 32) {
 332                dprintk("%s: too much I2C message to be transmitted (%i).\
 333                                Maximum is 32", __func__, num);
 334                return -ENOMEM;
 335        }
 336
 337        dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
 338
 339        if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
 340                dprintk("could not acquire lock");
 341                return -EINVAL;
 342        }
 343        memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
 344
 345        /* open the gate */
 346        dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
 347        mst->msg[0].addr = mst->i2c_addr;
 348        mst->msg[0].buf = &mst->i2c_write_buffer[0];
 349        mst->msg[0].len = 4;
 350
 351        memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
 352
 353        /* close the gate */
 354        dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
 355        mst->msg[num + 1].addr = mst->i2c_addr;
 356        mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
 357        mst->msg[num + 1].len = 4;
 358
 359        ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
 360                        num : -EIO);
 361        mutex_unlock(&mst->i2c_buffer_lock);
 362        return ret;
 363}
 364
 365static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
 366        .master_xfer = dibx000_i2c_gated_tuner_xfer,
 367        .functionality = dibx000_i2c_func,
 368};
 369
 370struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
 371                                                enum dibx000_i2c_interface intf,
 372                                                int gating)
 373{
 374        struct i2c_adapter *i2c = NULL;
 375
 376        switch (intf) {
 377        case DIBX000_I2C_INTERFACE_TUNER:
 378                if (gating)
 379                        i2c = &mst->gated_tuner_i2c_adap;
 380                break;
 381        case DIBX000_I2C_INTERFACE_GPIO_1_2:
 382                if (!gating)
 383                        i2c = &mst->master_i2c_adap_gpio12;
 384                break;
 385        case DIBX000_I2C_INTERFACE_GPIO_3_4:
 386                if (!gating)
 387                        i2c = &mst->master_i2c_adap_gpio34;
 388                break;
 389        case DIBX000_I2C_INTERFACE_GPIO_6_7:
 390                if (gating)
 391                        i2c = &mst->master_i2c_adap_gpio67;
 392                break;
 393        default:
 394                printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
 395                break;
 396        }
 397
 398        return i2c;
 399}
 400
 401EXPORT_SYMBOL(dibx000_get_i2c_adapter);
 402
 403void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
 404{
 405        /* initialize the i2c-master by closing the gate */
 406        u8 tx[4];
 407        struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
 408
 409        dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
 410        i2c_transfer(mst->i2c_adap, &m, 1);
 411        mst->selected_interface = 0xff; // the first time force a select of the I2C
 412        dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
 413}
 414
 415EXPORT_SYMBOL(dibx000_reset_i2c_master);
 416
 417static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
 418                                struct i2c_algorithm *algo, const char *name,
 419                                struct dibx000_i2c_master *mst)
 420{
 421        strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
 422        i2c_adap->algo = algo;
 423        i2c_adap->algo_data = NULL;
 424        i2c_set_adapdata(i2c_adap, mst);
 425        if (i2c_add_adapter(i2c_adap) < 0)
 426                return -ENODEV;
 427        return 0;
 428}
 429
 430int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
 431                                struct i2c_adapter *i2c_adap, u8 i2c_addr)
 432{
 433        int ret;
 434
 435        mutex_init(&mst->i2c_buffer_lock);
 436        if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
 437                dprintk("could not acquire lock");
 438                return -EINVAL;
 439        }
 440        memset(mst->msg, 0, sizeof(struct i2c_msg));
 441        mst->msg[0].addr = i2c_addr >> 1;
 442        mst->msg[0].flags = 0;
 443        mst->msg[0].buf = mst->i2c_write_buffer;
 444        mst->msg[0].len = 4;
 445
 446        mst->device_rev = device_rev;
 447        mst->i2c_adap = i2c_adap;
 448        mst->i2c_addr = i2c_addr >> 1;
 449
 450        if (device_rev == DIB7000P || device_rev == DIB8000)
 451                mst->base_reg = 1024;
 452        else
 453                mst->base_reg = 768;
 454
 455        mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
 456        if (i2c_adapter_init
 457                        (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
 458                         "DiBX000 tuner I2C bus", mst) != 0)
 459                printk(KERN_ERR
 460                                "DiBX000: could not initialize the tuner i2c_adapter\n");
 461
 462        mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
 463        if (i2c_adapter_init
 464                        (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
 465                         "DiBX000 master GPIO12 I2C bus", mst) != 0)
 466                printk(KERN_ERR
 467                                "DiBX000: could not initialize the master i2c_adapter\n");
 468
 469        mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
 470        if (i2c_adapter_init
 471                        (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
 472                         "DiBX000 master GPIO34 I2C bus", mst) != 0)
 473                printk(KERN_ERR
 474                                "DiBX000: could not initialize the master i2c_adapter\n");
 475
 476        mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
 477        if (i2c_adapter_init
 478                        (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
 479                         "DiBX000 master GPIO67 I2C bus", mst) != 0)
 480                printk(KERN_ERR
 481                                "DiBX000: could not initialize the master i2c_adapter\n");
 482
 483        /* initialize the i2c-master by closing the gate */
 484        dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
 485
 486        ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
 487        mutex_unlock(&mst->i2c_buffer_lock);
 488
 489        return ret;
 490}
 491
 492EXPORT_SYMBOL(dibx000_init_i2c_master);
 493
 494void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
 495{
 496        i2c_del_adapter(&mst->gated_tuner_i2c_adap);
 497        i2c_del_adapter(&mst->master_i2c_adap_gpio12);
 498        i2c_del_adapter(&mst->master_i2c_adap_gpio34);
 499        i2c_del_adapter(&mst->master_i2c_adap_gpio67);
 500}
 501EXPORT_SYMBOL(dibx000_exit_i2c_master);
 502
 503
 504u32 systime(void)
 505{
 506        struct timespec t;
 507
 508        t = current_kernel_time();
 509        return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
 510}
 511EXPORT_SYMBOL(systime);
 512
 513MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
 514MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
 515MODULE_LICENSE("GPL");
 516