root/drivers/media/dvb-frontends/dibx000_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dibx000_write_word
  2. dibx000_read_word
  3. dibx000_is_i2c_done
  4. dibx000_master_i2c_write
  5. dibx000_master_i2c_read
  6. dibx000_i2c_set_speed
  7. dibx000_i2c_func
  8. dibx000_i2c_select_interface
  9. dibx000_i2c_master_xfer_gpio12
  10. dibx000_i2c_master_xfer_gpio34
  11. dibx000_i2c_gate_ctrl
  12. dibx000_i2c_gated_gpio67_xfer
  13. dibx000_i2c_gated_tuner_xfer
  14. dibx000_get_i2c_adapter
  15. dibx000_reset_i2c_master
  16. i2c_adapter_init
  17. dibx000_init_i2c_master
  18. dibx000_exit_i2c_master

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

/* [<][>][^][v][top][bottom][index][help] */