0001
0002 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0003
0004 #include <linux/i2c.h>
0005 #include <linux/mutex.h>
0006 #include <linux/module.h>
0007
0008 #include "dibx000_common.h"
0009
0010 static int debug;
0011 module_param(debug, int, 0644);
0012 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
0013
0014 #define dprintk(fmt, arg...) do { \
0015 if (debug) \
0016 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
0017 __func__, ##arg); \
0018 } while (0)
0019
0020 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
0021 {
0022 int ret;
0023
0024 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0025 dprintk("could not acquire lock\n");
0026 return -EINVAL;
0027 }
0028
0029 mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
0030 mst->i2c_write_buffer[1] = reg & 0xff;
0031 mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
0032 mst->i2c_write_buffer[3] = val & 0xff;
0033
0034 memset(mst->msg, 0, sizeof(struct i2c_msg));
0035 mst->msg[0].addr = mst->i2c_addr;
0036 mst->msg[0].flags = 0;
0037 mst->msg[0].buf = mst->i2c_write_buffer;
0038 mst->msg[0].len = 4;
0039
0040 ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
0041 mutex_unlock(&mst->i2c_buffer_lock);
0042
0043 return ret;
0044 }
0045
0046 static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
0047 {
0048 u16 ret;
0049
0050 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0051 dprintk("could not acquire lock\n");
0052 return 0;
0053 }
0054
0055 mst->i2c_write_buffer[0] = reg >> 8;
0056 mst->i2c_write_buffer[1] = reg & 0xff;
0057
0058 memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
0059 mst->msg[0].addr = mst->i2c_addr;
0060 mst->msg[0].flags = 0;
0061 mst->msg[0].buf = mst->i2c_write_buffer;
0062 mst->msg[0].len = 2;
0063 mst->msg[1].addr = mst->i2c_addr;
0064 mst->msg[1].flags = I2C_M_RD;
0065 mst->msg[1].buf = mst->i2c_read_buffer;
0066 mst->msg[1].len = 2;
0067
0068 if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
0069 dprintk("i2c read error on %d\n", reg);
0070
0071 ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
0072 mutex_unlock(&mst->i2c_buffer_lock);
0073
0074 return ret;
0075 }
0076
0077 static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
0078 {
0079 int i = 100;
0080 u16 status;
0081
0082 while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
0083 ;
0084
0085
0086 if (i == 0)
0087 return -EREMOTEIO;
0088
0089
0090 if ((status & 0x0080) == 0)
0091 return -EREMOTEIO;
0092
0093 return 0;
0094 }
0095
0096 static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
0097 {
0098 u16 data;
0099 u16 da;
0100 u16 i;
0101 u16 txlen = msg->len, len;
0102 const u8 *b = msg->buf;
0103
0104 while (txlen) {
0105 dibx000_read_word(mst, mst->base_reg + 2);
0106
0107 len = txlen > 8 ? 8 : txlen;
0108 for (i = 0; i < len; i += 2) {
0109 data = *b++ << 8;
0110 if (i+1 < len)
0111 data |= *b++;
0112 dibx000_write_word(mst, mst->base_reg, data);
0113 }
0114 da = (((u8) (msg->addr)) << 9) |
0115 (1 << 8) |
0116 (1 << 7) |
0117 (0 << 6) |
0118 (0 << 5) |
0119 ((len & 0x7) << 2) |
0120 (0 << 1) |
0121 (0 << 0);
0122
0123 if (txlen == msg->len)
0124 da |= 1 << 5;
0125
0126 if (txlen-len == 0 && stop)
0127 da |= 1 << 6;
0128
0129 dibx000_write_word(mst, mst->base_reg+1, da);
0130
0131 if (dibx000_is_i2c_done(mst) != 0)
0132 return -EREMOTEIO;
0133 txlen -= len;
0134 }
0135
0136 return 0;
0137 }
0138
0139 static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
0140 {
0141 u16 da;
0142 u8 *b = msg->buf;
0143 u16 rxlen = msg->len, len;
0144
0145 while (rxlen) {
0146 len = rxlen > 8 ? 8 : rxlen;
0147 da = (((u8) (msg->addr)) << 9) |
0148 (1 << 8) |
0149 (1 << 7) |
0150 (0 << 6) |
0151 (0 << 5) |
0152 ((len & 0x7) << 2) |
0153 (1 << 1) |
0154 (0 << 0);
0155
0156 if (rxlen == msg->len)
0157 da |= 1 << 5;
0158
0159 if (rxlen-len == 0)
0160 da |= 1 << 6;
0161 dibx000_write_word(mst, mst->base_reg+1, da);
0162
0163 if (dibx000_is_i2c_done(mst) != 0)
0164 return -EREMOTEIO;
0165
0166 rxlen -= len;
0167
0168 while (len) {
0169 da = dibx000_read_word(mst, mst->base_reg);
0170 *b++ = (da >> 8) & 0xff;
0171 len--;
0172 if (len >= 1) {
0173 *b++ = da & 0xff;
0174 len--;
0175 }
0176 }
0177 }
0178
0179 return 0;
0180 }
0181
0182 int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
0183 {
0184 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0185
0186 if (mst->device_rev < DIB7000MC && speed < 235)
0187 speed = 235;
0188 return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
0189
0190 }
0191 EXPORT_SYMBOL(dibx000_i2c_set_speed);
0192
0193 static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
0194 {
0195 return I2C_FUNC_I2C;
0196 }
0197
0198 static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
0199 enum dibx000_i2c_interface intf)
0200 {
0201 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
0202 dprintk("selecting interface: %d\n", intf);
0203 mst->selected_interface = intf;
0204 return dibx000_write_word(mst, mst->base_reg + 4, intf);
0205 }
0206 return 0;
0207 }
0208
0209 static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
0210 {
0211 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0212 int msg_index;
0213 int ret = 0;
0214
0215 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
0216 for (msg_index = 0; msg_index < num; msg_index++) {
0217 if (msg[msg_index].flags & I2C_M_RD) {
0218 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
0219 if (ret != 0)
0220 return 0;
0221 } else {
0222 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
0223 if (ret != 0)
0224 return 0;
0225 }
0226 }
0227
0228 return num;
0229 }
0230
0231 static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
0232 {
0233 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0234 int msg_index;
0235 int ret = 0;
0236
0237 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
0238 for (msg_index = 0; msg_index < num; msg_index++) {
0239 if (msg[msg_index].flags & I2C_M_RD) {
0240 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
0241 if (ret != 0)
0242 return 0;
0243 } else {
0244 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
0245 if (ret != 0)
0246 return 0;
0247 }
0248 }
0249
0250 return num;
0251 }
0252
0253 static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
0254 .master_xfer = dibx000_i2c_master_xfer_gpio12,
0255 .functionality = dibx000_i2c_func,
0256 };
0257
0258 static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
0259 .master_xfer = dibx000_i2c_master_xfer_gpio34,
0260 .functionality = dibx000_i2c_func,
0261 };
0262
0263 static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
0264 u8 addr, int onoff)
0265 {
0266 u16 val;
0267
0268
0269 if (onoff)
0270 val = addr << 8;
0271 else
0272 val = 1 << 7;
0273
0274 if (mst->device_rev > DIB7000)
0275 val <<= 1;
0276
0277 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
0278 tx[1] = ((mst->base_reg + 1) & 0xff);
0279 tx[2] = val >> 8;
0280 tx[3] = val & 0xff;
0281
0282 return 0;
0283 }
0284
0285 static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
0286 struct i2c_msg msg[], int num)
0287 {
0288 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0289 int ret;
0290
0291 if (num > 32) {
0292 dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
0293 __func__, num);
0294 return -ENOMEM;
0295 }
0296
0297 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
0298
0299 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0300 dprintk("could not acquire lock\n");
0301 return -EINVAL;
0302 }
0303
0304 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
0305
0306
0307 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
0308 mst->msg[0].addr = mst->i2c_addr;
0309 mst->msg[0].buf = &mst->i2c_write_buffer[0];
0310 mst->msg[0].len = 4;
0311
0312 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
0313
0314
0315 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
0316 mst->msg[num + 1].addr = mst->i2c_addr;
0317 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
0318 mst->msg[num + 1].len = 4;
0319
0320 ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
0321 num : -EIO);
0322
0323 mutex_unlock(&mst->i2c_buffer_lock);
0324 return ret;
0325 }
0326
0327 static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
0328 .master_xfer = dibx000_i2c_gated_gpio67_xfer,
0329 .functionality = dibx000_i2c_func,
0330 };
0331
0332 static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
0333 struct i2c_msg msg[], int num)
0334 {
0335 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
0336 int ret;
0337
0338 if (num > 32) {
0339 dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
0340 __func__, num);
0341 return -ENOMEM;
0342 }
0343
0344 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
0345
0346 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0347 dprintk("could not acquire lock\n");
0348 return -EINVAL;
0349 }
0350 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
0351
0352
0353 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
0354 mst->msg[0].addr = mst->i2c_addr;
0355 mst->msg[0].buf = &mst->i2c_write_buffer[0];
0356 mst->msg[0].len = 4;
0357
0358 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
0359
0360
0361 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
0362 mst->msg[num + 1].addr = mst->i2c_addr;
0363 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
0364 mst->msg[num + 1].len = 4;
0365
0366 ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
0367 num : -EIO);
0368 mutex_unlock(&mst->i2c_buffer_lock);
0369 return ret;
0370 }
0371
0372 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
0373 .master_xfer = dibx000_i2c_gated_tuner_xfer,
0374 .functionality = dibx000_i2c_func,
0375 };
0376
0377 struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
0378 enum dibx000_i2c_interface intf,
0379 int gating)
0380 {
0381 struct i2c_adapter *i2c = NULL;
0382
0383 switch (intf) {
0384 case DIBX000_I2C_INTERFACE_TUNER:
0385 if (gating)
0386 i2c = &mst->gated_tuner_i2c_adap;
0387 break;
0388 case DIBX000_I2C_INTERFACE_GPIO_1_2:
0389 if (!gating)
0390 i2c = &mst->master_i2c_adap_gpio12;
0391 break;
0392 case DIBX000_I2C_INTERFACE_GPIO_3_4:
0393 if (!gating)
0394 i2c = &mst->master_i2c_adap_gpio34;
0395 break;
0396 case DIBX000_I2C_INTERFACE_GPIO_6_7:
0397 if (gating)
0398 i2c = &mst->master_i2c_adap_gpio67;
0399 break;
0400 default:
0401 pr_err("incorrect I2C interface selected\n");
0402 break;
0403 }
0404
0405 return i2c;
0406 }
0407
0408 EXPORT_SYMBOL(dibx000_get_i2c_adapter);
0409
0410 void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
0411 {
0412
0413 u8 tx[4];
0414 struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
0415
0416 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
0417 i2c_transfer(mst->i2c_adap, &m, 1);
0418 mst->selected_interface = 0xff;
0419 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
0420 }
0421
0422 EXPORT_SYMBOL(dibx000_reset_i2c_master);
0423
0424 static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
0425 struct i2c_algorithm *algo, const char *name,
0426 struct dibx000_i2c_master *mst)
0427 {
0428 strscpy(i2c_adap->name, name, sizeof(i2c_adap->name));
0429 i2c_adap->algo = algo;
0430 i2c_adap->algo_data = NULL;
0431 i2c_set_adapdata(i2c_adap, mst);
0432 if (i2c_add_adapter(i2c_adap) < 0)
0433 return -ENODEV;
0434 return 0;
0435 }
0436
0437 int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
0438 struct i2c_adapter *i2c_adap, u8 i2c_addr)
0439 {
0440 int ret;
0441
0442 mutex_init(&mst->i2c_buffer_lock);
0443 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
0444 dprintk("could not acquire lock\n");
0445 return -EINVAL;
0446 }
0447 memset(mst->msg, 0, sizeof(struct i2c_msg));
0448 mst->msg[0].addr = i2c_addr >> 1;
0449 mst->msg[0].flags = 0;
0450 mst->msg[0].buf = mst->i2c_write_buffer;
0451 mst->msg[0].len = 4;
0452
0453 mst->device_rev = device_rev;
0454 mst->i2c_adap = i2c_adap;
0455 mst->i2c_addr = i2c_addr >> 1;
0456
0457 if (device_rev == DIB7000P || device_rev == DIB8000)
0458 mst->base_reg = 1024;
0459 else
0460 mst->base_reg = 768;
0461
0462 mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
0463 if (i2c_adapter_init
0464 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
0465 "DiBX000 tuner I2C bus", mst) != 0)
0466 pr_err("could not initialize the tuner i2c_adapter\n");
0467
0468 mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
0469 if (i2c_adapter_init
0470 (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
0471 "DiBX000 master GPIO12 I2C bus", mst) != 0)
0472 pr_err("could not initialize the master i2c_adapter\n");
0473
0474 mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
0475 if (i2c_adapter_init
0476 (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
0477 "DiBX000 master GPIO34 I2C bus", mst) != 0)
0478 pr_err("could not initialize the master i2c_adapter\n");
0479
0480 mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
0481 if (i2c_adapter_init
0482 (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
0483 "DiBX000 master GPIO67 I2C bus", mst) != 0)
0484 pr_err("could not initialize the master i2c_adapter\n");
0485
0486
0487 dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
0488
0489 ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
0490 mutex_unlock(&mst->i2c_buffer_lock);
0491
0492 return ret;
0493 }
0494
0495 EXPORT_SYMBOL(dibx000_init_i2c_master);
0496
0497 void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
0498 {
0499 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
0500 i2c_del_adapter(&mst->master_i2c_adap_gpio12);
0501 i2c_del_adapter(&mst->master_i2c_adap_gpio34);
0502 i2c_del_adapter(&mst->master_i2c_adap_gpio67);
0503 }
0504 EXPORT_SYMBOL(dibx000_exit_i2c_master);
0505
0506 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
0507 MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
0508 MODULE_LICENSE("GPL");