0001
0002
0003
0004
0005
0006
0007 #include <linux/i2c.h>
0008 #include <linux/module.h>
0009 #include <media/i2c/ir-kbd-i2c.h>
0010 #include "pvrusb2-i2c-core.h"
0011 #include "pvrusb2-hdw-internal.h"
0012 #include "pvrusb2-debug.h"
0013 #include "pvrusb2-fx2-cmd.h"
0014 #include "pvrusb2.h"
0015
0016 #define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
0017
0018
0019
0020
0021
0022
0023
0024
0025 static unsigned int i2c_scan;
0026 module_param(i2c_scan, int, S_IRUGO|S_IWUSR);
0027 MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
0028
0029 static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
0030 module_param_array(ir_mode, int, NULL, 0444);
0031 MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
0032
0033 static int pvr2_disable_ir_video;
0034 module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
0035 int, S_IRUGO|S_IWUSR);
0036 MODULE_PARM_DESC(disable_autoload_ir_video,
0037 "1=do not try to autoload ir_video IR receiver");
0038
0039 static int pvr2_i2c_write(struct pvr2_hdw *hdw,
0040 u8 i2c_addr,
0041 u8 *data,
0042 u16 length)
0043 {
0044
0045 int ret;
0046
0047
0048 if (!data) length = 0;
0049 if (length > (sizeof(hdw->cmd_buffer) - 3)) {
0050 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0051 "Killing an I2C write to %u that is too large (desired=%u limit=%u)",
0052 i2c_addr,
0053 length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3));
0054 return -ENOTSUPP;
0055 }
0056
0057 LOCK_TAKE(hdw->ctl_lock);
0058
0059
0060 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
0061
0062
0063 hdw->cmd_buffer[0] = FX2CMD_I2C_WRITE;
0064 hdw->cmd_buffer[1] = i2c_addr;
0065 hdw->cmd_buffer[2] = length;
0066 if (length) memcpy(hdw->cmd_buffer + 3, data, length);
0067
0068
0069 ret = pvr2_send_request(hdw,
0070 hdw->cmd_buffer,
0071 length + 3,
0072 hdw->cmd_buffer,
0073 1);
0074 if (!ret) {
0075 if (hdw->cmd_buffer[0] != 8) {
0076 ret = -EIO;
0077 if (hdw->cmd_buffer[0] != 7) {
0078 trace_i2c("unexpected status from i2_write[%d]: %d",
0079 i2c_addr,hdw->cmd_buffer[0]);
0080 }
0081 }
0082 }
0083
0084 LOCK_GIVE(hdw->ctl_lock);
0085
0086 return ret;
0087 }
0088
0089 static int pvr2_i2c_read(struct pvr2_hdw *hdw,
0090 u8 i2c_addr,
0091 u8 *data,
0092 u16 dlen,
0093 u8 *res,
0094 u16 rlen)
0095 {
0096
0097 int ret;
0098
0099
0100 if (!data) dlen = 0;
0101 if (dlen > (sizeof(hdw->cmd_buffer) - 4)) {
0102 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0103 "Killing an I2C read to %u that has wlen too large (desired=%u limit=%u)",
0104 i2c_addr,
0105 dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4));
0106 return -ENOTSUPP;
0107 }
0108 if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) {
0109 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0110 "Killing an I2C read to %u that has rlen too large (desired=%u limit=%u)",
0111 i2c_addr,
0112 rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1));
0113 return -ENOTSUPP;
0114 }
0115
0116 LOCK_TAKE(hdw->ctl_lock);
0117
0118
0119 memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer));
0120
0121
0122 hdw->cmd_buffer[0] = FX2CMD_I2C_READ;
0123 hdw->cmd_buffer[1] = dlen;
0124 hdw->cmd_buffer[2] = rlen;
0125
0126 hdw->cmd_buffer[3] = i2c_addr;
0127 if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen);
0128
0129
0130 ret = pvr2_send_request(hdw,
0131 hdw->cmd_buffer,
0132 4 + dlen,
0133 hdw->cmd_buffer,
0134 rlen + 1);
0135 if (!ret) {
0136 if (hdw->cmd_buffer[0] != 8) {
0137 ret = -EIO;
0138 if (hdw->cmd_buffer[0] != 7) {
0139 trace_i2c("unexpected status from i2_read[%d]: %d",
0140 i2c_addr,hdw->cmd_buffer[0]);
0141 }
0142 }
0143 }
0144
0145
0146 if (res && rlen) {
0147 if (ret) {
0148
0149 memset(res, 0, rlen);
0150 } else {
0151 memcpy(res, hdw->cmd_buffer + 1, rlen);
0152 }
0153 }
0154
0155 LOCK_GIVE(hdw->ctl_lock);
0156
0157 return ret;
0158 }
0159
0160
0161
0162 static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
0163 u8 i2c_addr,
0164 u8 *wdata,
0165 u16 wlen,
0166 u8 *rdata,
0167 u16 rlen)
0168 {
0169 if (!rdata) rlen = 0;
0170 if (!wdata) wlen = 0;
0171 if (rlen || !wlen) {
0172 return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen);
0173 } else {
0174 return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen);
0175 }
0176 }
0177
0178
0179
0180
0181
0182
0183
0184
0185 static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
0186 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
0187 {
0188 u8 dat[4];
0189 unsigned int stat;
0190
0191 if (!(rlen || wlen)) {
0192
0193 return 0;
0194 }
0195
0196
0197 if ((wlen != 0) || (rlen == 0)) return -EIO;
0198
0199 if (rlen < 3) {
0200
0201
0202
0203
0204
0205
0206
0207 if (rlen > 0) rdata[0] = 0;
0208 if (rlen > 1) rdata[1] = 0;
0209 return 0;
0210 }
0211
0212
0213 LOCK_TAKE(hdw->ctl_lock); do {
0214 hdw->cmd_buffer[0] = FX2CMD_GET_IR_CODE;
0215 stat = pvr2_send_request(hdw,
0216 hdw->cmd_buffer,1,
0217 hdw->cmd_buffer,4);
0218 dat[0] = hdw->cmd_buffer[0];
0219 dat[1] = hdw->cmd_buffer[1];
0220 dat[2] = hdw->cmd_buffer[2];
0221 dat[3] = hdw->cmd_buffer[3];
0222 } while (0); LOCK_GIVE(hdw->ctl_lock);
0223
0224
0225 if (stat != 0) return stat;
0226
0227
0228
0229 rdata[2] = 0xc1;
0230 if (dat[0] != 1) {
0231
0232 rdata[0] = 0;
0233 rdata[1] = 0;
0234 } else {
0235 u16 val;
0236
0237
0238 val = dat[1];
0239 val <<= 8;
0240 val |= dat[2];
0241 val >>= 1;
0242 val &= ~0x0003;
0243 val |= 0x8000;
0244 rdata[0] = (val >> 8) & 0xffu;
0245 rdata[1] = val & 0xffu;
0246 }
0247
0248 return 0;
0249 }
0250
0251
0252
0253
0254
0255 static int i2c_hack_wm8775(struct pvr2_hdw *hdw,
0256 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
0257 {
0258 if (!(rlen || wlen)) {
0259
0260 return 0;
0261 }
0262 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
0263 }
0264
0265
0266
0267
0268 static int i2c_black_hole(struct pvr2_hdw *hdw,
0269 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
0270 {
0271 return -EIO;
0272 }
0273
0274
0275
0276
0277
0278
0279
0280
0281 static int i2c_hack_cx25840(struct pvr2_hdw *hdw,
0282 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
0283 {
0284 int ret;
0285 unsigned int subaddr;
0286 u8 wbuf[2];
0287 int state = hdw->i2c_cx25840_hack_state;
0288
0289 if (!(rlen || wlen)) {
0290
0291
0292
0293 return 0;
0294 }
0295
0296 if (state == 3) {
0297 return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen);
0298 }
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 if (wlen == 0) {
0309 switch (state) {
0310 case 1: subaddr = 0x0100; break;
0311 case 2: subaddr = 0x0101; break;
0312 default: goto fail;
0313 }
0314 } else if (wlen == 2) {
0315 subaddr = (wdata[0] << 8) | wdata[1];
0316 switch (subaddr) {
0317 case 0x0100: state = 1; break;
0318 case 0x0101: state = 2; break;
0319 default: goto fail;
0320 }
0321 } else {
0322 goto fail;
0323 }
0324 if (!rlen) goto success;
0325 state = 0;
0326 if (rlen != 1) goto fail;
0327
0328
0329
0330 wbuf[0] = subaddr >> 8;
0331 wbuf[1] = subaddr;
0332 ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen);
0333
0334 if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) {
0335 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0336 "***WARNING*** Detected a wedged cx25840 chip; the device will not work.");
0337 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0338 "***WARNING*** Try power cycling the pvrusb2 device.");
0339 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
0340 "***WARNING*** Disabling further access to the device to prevent other foul-ups.");
0341
0342 hdw->i2c_func[0x44] = NULL;
0343 pvr2_hdw_render_useless(hdw);
0344 goto fail;
0345 }
0346
0347
0348 pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK.");
0349 state = 3;
0350
0351 success:
0352 hdw->i2c_cx25840_hack_state = state;
0353 return 0;
0354
0355 fail:
0356 hdw->i2c_cx25840_hack_state = state;
0357 return -EIO;
0358 }
0359
0360
0361
0362 static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap,
0363 struct i2c_msg msgs[],
0364 int num)
0365 {
0366 int ret = -ENOTSUPP;
0367 pvr2_i2c_func funcp = NULL;
0368 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data);
0369
0370 if (!num) {
0371 ret = -EINVAL;
0372 goto done;
0373 }
0374 if (msgs[0].addr < PVR2_I2C_FUNC_CNT) {
0375 funcp = hdw->i2c_func[msgs[0].addr];
0376 }
0377 if (!funcp) {
0378 ret = -EIO;
0379 goto done;
0380 }
0381
0382 if (num == 1) {
0383 if (msgs[0].flags & I2C_M_RD) {
0384
0385 u16 tcnt,bcnt,offs;
0386 if (!msgs[0].len) {
0387
0388 if (funcp(hdw,msgs[0].addr,NULL,0,NULL,0)) {
0389 ret = -EIO;
0390 goto done;
0391 }
0392 ret = 1;
0393 goto done;
0394 }
0395
0396
0397
0398 tcnt = msgs[0].len;
0399 offs = 0;
0400 while (tcnt) {
0401 bcnt = tcnt;
0402 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
0403 bcnt = sizeof(hdw->cmd_buffer)-1;
0404 }
0405 if (funcp(hdw,msgs[0].addr,NULL,0,
0406 msgs[0].buf+offs,bcnt)) {
0407 ret = -EIO;
0408 goto done;
0409 }
0410 offs += bcnt;
0411 tcnt -= bcnt;
0412 }
0413 ret = 1;
0414 goto done;
0415 } else {
0416
0417 ret = 1;
0418 if (funcp(hdw,msgs[0].addr,
0419 msgs[0].buf,msgs[0].len,NULL,0)) {
0420 ret = -EIO;
0421 }
0422 goto done;
0423 }
0424 } else if (num == 2) {
0425 if (msgs[0].addr != msgs[1].addr) {
0426 trace_i2c("i2c refusing 2 phase transfer with conflicting target addresses");
0427 ret = -ENOTSUPP;
0428 goto done;
0429 }
0430 if ((!((msgs[0].flags & I2C_M_RD))) &&
0431 (msgs[1].flags & I2C_M_RD)) {
0432 u16 tcnt,bcnt,wcnt,offs;
0433
0434
0435
0436
0437 tcnt = msgs[1].len;
0438 wcnt = msgs[0].len;
0439 offs = 0;
0440 while (tcnt || wcnt) {
0441 bcnt = tcnt;
0442 if (bcnt > sizeof(hdw->cmd_buffer)-1) {
0443 bcnt = sizeof(hdw->cmd_buffer)-1;
0444 }
0445 if (funcp(hdw,msgs[0].addr,
0446 msgs[0].buf,wcnt,
0447 msgs[1].buf+offs,bcnt)) {
0448 ret = -EIO;
0449 goto done;
0450 }
0451 offs += bcnt;
0452 tcnt -= bcnt;
0453 wcnt = 0;
0454 }
0455 ret = 2;
0456 goto done;
0457 } else {
0458 trace_i2c("i2c refusing complex transfer read0=%d read1=%d",
0459 (msgs[0].flags & I2C_M_RD),
0460 (msgs[1].flags & I2C_M_RD));
0461 }
0462 } else {
0463 trace_i2c("i2c refusing %d phase transfer",num);
0464 }
0465
0466 done:
0467 if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) {
0468 unsigned int idx,offs,cnt;
0469 for (idx = 0; idx < num; idx++) {
0470 cnt = msgs[idx].len;
0471 pr_info("pvrusb2 i2c xfer %u/%u: addr=0x%x len=%d %s",
0472 idx+1,num,
0473 msgs[idx].addr,
0474 cnt,
0475 (msgs[idx].flags & I2C_M_RD ?
0476 "read" : "write"));
0477 if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) {
0478 if (cnt > 8) cnt = 8;
0479 pr_cont(" [");
0480 for (offs = 0; offs < cnt; offs++) {
0481 if (offs) pr_cont(" ");
0482 pr_cont("%02x", msgs[idx].buf[offs]);
0483 }
0484 if (offs < cnt) pr_cont(" ...");
0485 pr_cont("]");
0486 }
0487 if (idx+1 == num) {
0488 pr_cont(" result=%d", ret);
0489 }
0490 pr_cont("\n");
0491 }
0492 if (!num) {
0493 pr_info("pvrusb2 i2c xfer null transfer result=%d\n",
0494 ret);
0495 }
0496 }
0497 return ret;
0498 }
0499
0500 static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
0501 {
0502 return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
0503 }
0504
0505 static const struct i2c_algorithm pvr2_i2c_algo_template = {
0506 .master_xfer = pvr2_i2c_xfer,
0507 .functionality = pvr2_i2c_functionality,
0508 };
0509
0510 static const struct i2c_adapter pvr2_i2c_adap_template = {
0511 .owner = THIS_MODULE,
0512 .class = 0,
0513 };
0514
0515
0516
0517 static int do_i2c_probe(struct pvr2_hdw *hdw, int addr)
0518 {
0519 struct i2c_msg msg[1];
0520 int rc;
0521 msg[0].addr = 0;
0522 msg[0].flags = I2C_M_RD;
0523 msg[0].len = 0;
0524 msg[0].buf = NULL;
0525 msg[0].addr = addr;
0526 rc = i2c_transfer(&hdw->i2c_adap, msg, ARRAY_SIZE(msg));
0527 return rc == 1;
0528 }
0529
0530 static void do_i2c_scan(struct pvr2_hdw *hdw)
0531 {
0532 int i;
0533 pr_info("%s: i2c scan beginning\n", hdw->name);
0534 for (i = 0; i < 128; i++) {
0535 if (do_i2c_probe(hdw, i)) {
0536 pr_info("%s: i2c scan: found device @ 0x%x\n",
0537 hdw->name, i);
0538 }
0539 }
0540 pr_info("%s: i2c scan done.\n", hdw->name);
0541 }
0542
0543 static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
0544 {
0545 struct i2c_board_info info;
0546 struct IR_i2c_init_data *init_data = &hdw->ir_init_data;
0547 if (pvr2_disable_ir_video) {
0548 pvr2_trace(PVR2_TRACE_INFO,
0549 "Automatic binding of ir_video has been disabled.");
0550 return;
0551 }
0552 memset(&info, 0, sizeof(struct i2c_board_info));
0553 switch (hdw->ir_scheme_active) {
0554 case PVR2_IR_SCHEME_24XXX:
0555 case PVR2_IR_SCHEME_29XXX:
0556 init_data->ir_codes = RC_MAP_HAUPPAUGE;
0557 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
0558 init_data->type = RC_PROTO_BIT_RC5;
0559 init_data->name = hdw->hdw_desc->description;
0560 init_data->polling_interval = 100;
0561
0562 info.addr = 0x18;
0563 info.platform_data = init_data;
0564 strscpy(info.type, "ir_video", I2C_NAME_SIZE);
0565 pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
0566 info.type, info.addr);
0567 i2c_new_client_device(&hdw->i2c_adap, &info);
0568 break;
0569 case PVR2_IR_SCHEME_ZILOG:
0570 case PVR2_IR_SCHEME_24XXX_MCE:
0571 init_data->ir_codes = RC_MAP_HAUPPAUGE;
0572 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
0573 init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
0574 RC_PROTO_BIT_RC6_6A_32;
0575 init_data->name = hdw->hdw_desc->description;
0576
0577 info.addr = 0x71;
0578 info.platform_data = init_data;
0579 strscpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
0580 pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
0581 info.type, info.addr);
0582 i2c_new_client_device(&hdw->i2c_adap, &info);
0583 break;
0584 default:
0585
0586
0587 break;
0588 }
0589 }
0590
0591 void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
0592 {
0593 unsigned int idx;
0594
0595
0596
0597 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
0598 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
0599 }
0600
0601
0602 if (ir_mode[hdw->unit_number] == 0) {
0603 pr_info("%s: IR disabled\n", hdw->name);
0604 hdw->i2c_func[0x18] = i2c_black_hole;
0605 } else if (ir_mode[hdw->unit_number] == 1) {
0606 if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
0607
0608
0609 hdw->i2c_func[0x18] = i2c_24xxx_ir;
0610 }
0611 }
0612 if (hdw->hdw_desc->flag_has_cx25840) {
0613 hdw->i2c_func[0x44] = i2c_hack_cx25840;
0614 }
0615 if (hdw->hdw_desc->flag_has_wm8775) {
0616 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
0617 }
0618
0619
0620 hdw->i2c_adap = pvr2_i2c_adap_template;
0621 hdw->i2c_algo = pvr2_i2c_algo_template;
0622 strscpy(hdw->i2c_adap.name, hdw->name, sizeof(hdw->i2c_adap.name));
0623 hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
0624 hdw->i2c_adap.algo = &hdw->i2c_algo;
0625 hdw->i2c_adap.algo_data = hdw;
0626 hdw->i2c_linked = !0;
0627 i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
0628 i2c_add_adapter(&hdw->i2c_adap);
0629 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
0630
0631
0632
0633
0634
0635
0636 if (do_i2c_probe(hdw, 0x71)) {
0637 pvr2_trace(PVR2_TRACE_INFO,
0638 "Device has newer IR hardware; disabling unneeded virtual IR device");
0639 hdw->i2c_func[0x18] = NULL;
0640
0641 hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
0642 }
0643 }
0644 if (i2c_scan) do_i2c_scan(hdw);
0645
0646 pvr2_i2c_register_ir(hdw);
0647 }
0648
0649 void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
0650 {
0651 if (hdw->i2c_linked) {
0652 i2c_del_adapter(&hdw->i2c_adap);
0653 hdw->i2c_linked = 0;
0654 }
0655 }