0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "az6027.h"
0010
0011 #include "stb0899_drv.h"
0012 #include "stb0899_reg.h"
0013 #include "stb0899_cfg.h"
0014
0015 #include "stb6100.h"
0016 #include "stb6100_cfg.h"
0017 #include <media/dvb_ca_en50221.h>
0018
0019 int dvb_usb_az6027_debug;
0020 module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
0021 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
0022
0023 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
0024
0025 struct az6027_device_state {
0026 struct dvb_ca_en50221 ca;
0027 struct mutex ca_mutex;
0028 u8 power_state;
0029 };
0030
0031 static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
0032
0033
0034 { STB0899_DEV_ID , 0x30 },
0035 { STB0899_DISCNTRL1 , 0x32 },
0036 { STB0899_DISCNTRL2 , 0x80 },
0037 { STB0899_DISRX_ST0 , 0x04 },
0038 { STB0899_DISRX_ST1 , 0x00 },
0039 { STB0899_DISPARITY , 0x00 },
0040 { STB0899_DISSTATUS , 0x20 },
0041 { STB0899_DISF22 , 0x99 },
0042 { STB0899_DISF22RX , 0xa8 },
0043
0044 { STB0899_ACRPRESC , 0x11 },
0045 { STB0899_ACRDIV1 , 0x0a },
0046 { STB0899_ACRDIV2 , 0x05 },
0047 { STB0899_DACR1 , 0x00 },
0048 { STB0899_DACR2 , 0x00 },
0049 { STB0899_OUTCFG , 0x00 },
0050 { STB0899_MODECFG , 0x00 },
0051 { STB0899_IRQSTATUS_3 , 0xfe },
0052 { STB0899_IRQSTATUS_2 , 0x03 },
0053 { STB0899_IRQSTATUS_1 , 0x7c },
0054 { STB0899_IRQSTATUS_0 , 0xf4 },
0055 { STB0899_IRQMSK_3 , 0xf3 },
0056 { STB0899_IRQMSK_2 , 0xfc },
0057 { STB0899_IRQMSK_1 , 0xff },
0058 { STB0899_IRQMSK_0 , 0xff },
0059 { STB0899_IRQCFG , 0x00 },
0060 { STB0899_I2CCFG , 0x88 },
0061 { STB0899_I2CRPT , 0x58 },
0062 { STB0899_IOPVALUE5 , 0x00 },
0063 { STB0899_IOPVALUE4 , 0x33 },
0064 { STB0899_IOPVALUE3 , 0x6d },
0065 { STB0899_IOPVALUE2 , 0x90 },
0066 { STB0899_IOPVALUE1 , 0x60 },
0067 { STB0899_IOPVALUE0 , 0x00 },
0068 { STB0899_GPIO00CFG , 0x82 },
0069 { STB0899_GPIO01CFG , 0x82 },
0070 { STB0899_GPIO02CFG , 0x82 },
0071 { STB0899_GPIO03CFG , 0x82 },
0072 { STB0899_GPIO04CFG , 0x82 },
0073 { STB0899_GPIO05CFG , 0x82 },
0074 { STB0899_GPIO06CFG , 0x82 },
0075 { STB0899_GPIO07CFG , 0x82 },
0076 { STB0899_GPIO08CFG , 0x82 },
0077 { STB0899_GPIO09CFG , 0x82 },
0078 { STB0899_GPIO10CFG , 0x82 },
0079 { STB0899_GPIO11CFG , 0x82 },
0080 { STB0899_GPIO12CFG , 0x82 },
0081 { STB0899_GPIO13CFG , 0x82 },
0082 { STB0899_GPIO14CFG , 0x82 },
0083 { STB0899_GPIO15CFG , 0x82 },
0084 { STB0899_GPIO16CFG , 0x82 },
0085 { STB0899_GPIO17CFG , 0x82 },
0086 { STB0899_GPIO18CFG , 0x82 },
0087 { STB0899_GPIO19CFG , 0x82 },
0088 { STB0899_GPIO20CFG , 0x82 },
0089 { STB0899_SDATCFG , 0xb8 },
0090 { STB0899_SCLTCFG , 0xba },
0091 { STB0899_AGCRFCFG , 0x1c },
0092 { STB0899_GPIO22 , 0x82 },
0093 { STB0899_GPIO21 , 0x91 },
0094 { STB0899_DIRCLKCFG , 0x82 },
0095 { STB0899_CLKOUT27CFG , 0x7e },
0096 { STB0899_STDBYCFG , 0x82 },
0097 { STB0899_CS0CFG , 0x82 },
0098 { STB0899_CS1CFG , 0x82 },
0099 { STB0899_DISEQCOCFG , 0x20 },
0100 { STB0899_GPIO32CFG , 0x82 },
0101 { STB0899_GPIO33CFG , 0x82 },
0102 { STB0899_GPIO34CFG , 0x82 },
0103 { STB0899_GPIO35CFG , 0x82 },
0104 { STB0899_GPIO36CFG , 0x82 },
0105 { STB0899_GPIO37CFG , 0x82 },
0106 { STB0899_GPIO38CFG , 0x82 },
0107 { STB0899_GPIO39CFG , 0x82 },
0108 { STB0899_NCOARSE , 0x17 },
0109 { STB0899_SYNTCTRL , 0x02 },
0110 { STB0899_FILTCTRL , 0x00 },
0111 { STB0899_SYSCTRL , 0x01 },
0112 { STB0899_STOPCLK1 , 0x20 },
0113 { STB0899_STOPCLK2 , 0x00 },
0114 { STB0899_INTBUFSTATUS , 0x00 },
0115 { STB0899_INTBUFCTRL , 0x0a },
0116 { 0xffff , 0xff },
0117 };
0118
0119 static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
0120 { STB0899_DEMOD , 0x00 },
0121 { STB0899_RCOMPC , 0xc9 },
0122 { STB0899_AGC1CN , 0x01 },
0123 { STB0899_AGC1REF , 0x10 },
0124 { STB0899_RTC , 0x23 },
0125 { STB0899_TMGCFG , 0x4e },
0126 { STB0899_AGC2REF , 0x34 },
0127 { STB0899_TLSR , 0x84 },
0128 { STB0899_CFD , 0xf7 },
0129 { STB0899_ACLC , 0x87 },
0130 { STB0899_BCLC , 0x94 },
0131 { STB0899_EQON , 0x41 },
0132 { STB0899_LDT , 0xf1 },
0133 { STB0899_LDT2 , 0xe3 },
0134 { STB0899_EQUALREF , 0xb4 },
0135 { STB0899_TMGRAMP , 0x10 },
0136 { STB0899_TMGTHD , 0x30 },
0137 { STB0899_IDCCOMP , 0xfd },
0138 { STB0899_QDCCOMP , 0xff },
0139 { STB0899_POWERI , 0x0c },
0140 { STB0899_POWERQ , 0x0f },
0141 { STB0899_RCOMP , 0x6c },
0142 { STB0899_AGCIQIN , 0x80 },
0143 { STB0899_AGC2I1 , 0x06 },
0144 { STB0899_AGC2I2 , 0x00 },
0145 { STB0899_TLIR , 0x30 },
0146 { STB0899_RTF , 0x7f },
0147 { STB0899_DSTATUS , 0x00 },
0148 { STB0899_LDI , 0xbc },
0149 { STB0899_CFRM , 0xea },
0150 { STB0899_CFRL , 0x31 },
0151 { STB0899_NIRM , 0x2b },
0152 { STB0899_NIRL , 0x80 },
0153 { STB0899_ISYMB , 0x1d },
0154 { STB0899_QSYMB , 0xa6 },
0155 { STB0899_SFRH , 0x2f },
0156 { STB0899_SFRM , 0x68 },
0157 { STB0899_SFRL , 0x40 },
0158 { STB0899_SFRUPH , 0x2f },
0159 { STB0899_SFRUPM , 0x68 },
0160 { STB0899_SFRUPL , 0x40 },
0161 { STB0899_EQUAI1 , 0x02 },
0162 { STB0899_EQUAQ1 , 0xff },
0163 { STB0899_EQUAI2 , 0x04 },
0164 { STB0899_EQUAQ2 , 0x05 },
0165 { STB0899_EQUAI3 , 0x02 },
0166 { STB0899_EQUAQ3 , 0xfd },
0167 { STB0899_EQUAI4 , 0x03 },
0168 { STB0899_EQUAQ4 , 0x07 },
0169 { STB0899_EQUAI5 , 0x08 },
0170 { STB0899_EQUAQ5 , 0xf5 },
0171 { STB0899_DSTATUS2 , 0x00 },
0172 { STB0899_VSTATUS , 0x00 },
0173 { STB0899_VERROR , 0x86 },
0174 { STB0899_IQSWAP , 0x2a },
0175 { STB0899_ECNT1M , 0x00 },
0176 { STB0899_ECNT1L , 0x00 },
0177 { STB0899_ECNT2M , 0x00 },
0178 { STB0899_ECNT2L , 0x00 },
0179 { STB0899_ECNT3M , 0x0a },
0180 { STB0899_ECNT3L , 0xad },
0181 { STB0899_FECAUTO1 , 0x06 },
0182 { STB0899_FECM , 0x01 },
0183 { STB0899_VTH12 , 0xb0 },
0184 { STB0899_VTH23 , 0x7a },
0185 { STB0899_VTH34 , 0x58 },
0186 { STB0899_VTH56 , 0x38 },
0187 { STB0899_VTH67 , 0x34 },
0188 { STB0899_VTH78 , 0x24 },
0189 { STB0899_PRVIT , 0xff },
0190 { STB0899_VITSYNC , 0x19 },
0191 { STB0899_RSULC , 0xb1 },
0192 { STB0899_TSULC , 0x42 },
0193 { STB0899_RSLLC , 0x41 },
0194 { STB0899_TSLPL , 0x12 },
0195 { STB0899_TSCFGH , 0x0c },
0196 { STB0899_TSCFGM , 0x00 },
0197 { STB0899_TSCFGL , 0x00 },
0198 { STB0899_TSOUT , 0x69 },
0199 { STB0899_RSSYNCDEL , 0x00 },
0200 { STB0899_TSINHDELH , 0x02 },
0201 { STB0899_TSINHDELM , 0x00 },
0202 { STB0899_TSINHDELL , 0x00 },
0203 { STB0899_TSLLSTKM , 0x1b },
0204 { STB0899_TSLLSTKL , 0xb3 },
0205 { STB0899_TSULSTKM , 0x00 },
0206 { STB0899_TSULSTKL , 0x00 },
0207 { STB0899_PCKLENUL , 0xbc },
0208 { STB0899_PCKLENLL , 0xcc },
0209 { STB0899_RSPCKLEN , 0xbd },
0210 { STB0899_TSSTATUS , 0x90 },
0211 { STB0899_ERRCTRL1 , 0xb6 },
0212 { STB0899_ERRCTRL2 , 0x95 },
0213 { STB0899_ERRCTRL3 , 0x8d },
0214 { STB0899_DMONMSK1 , 0x27 },
0215 { STB0899_DMONMSK0 , 0x03 },
0216 { STB0899_DEMAPVIT , 0x5c },
0217 { STB0899_PLPARM , 0x19 },
0218 { STB0899_PDELCTRL , 0x48 },
0219 { STB0899_PDELCTRL2 , 0x00 },
0220 { STB0899_BBHCTRL1 , 0x00 },
0221 { STB0899_BBHCTRL2 , 0x00 },
0222 { STB0899_HYSTTHRESH , 0x77 },
0223 { STB0899_MATCSTM , 0x00 },
0224 { STB0899_MATCSTL , 0x00 },
0225 { STB0899_UPLCSTM , 0x00 },
0226 { STB0899_UPLCSTL , 0x00 },
0227 { STB0899_DFLCSTM , 0x00 },
0228 { STB0899_DFLCSTL , 0x00 },
0229 { STB0899_SYNCCST , 0x00 },
0230 { STB0899_SYNCDCSTM , 0x00 },
0231 { STB0899_SYNCDCSTL , 0x00 },
0232 { STB0899_ISI_ENTRY , 0x00 },
0233 { STB0899_ISI_BIT_EN , 0x00 },
0234 { STB0899_MATSTRM , 0xf0 },
0235 { STB0899_MATSTRL , 0x02 },
0236 { STB0899_UPLSTRM , 0x45 },
0237 { STB0899_UPLSTRL , 0x60 },
0238 { STB0899_DFLSTRM , 0xe3 },
0239 { STB0899_DFLSTRL , 0x00 },
0240 { STB0899_SYNCSTR , 0x47 },
0241 { STB0899_SYNCDSTRM , 0x05 },
0242 { STB0899_SYNCDSTRL , 0x18 },
0243 { STB0899_CFGPDELSTATUS1 , 0x19 },
0244 { STB0899_CFGPDELSTATUS2 , 0x2b },
0245 { STB0899_BBFERRORM , 0x00 },
0246 { STB0899_BBFERRORL , 0x01 },
0247 { STB0899_UPKTERRORM , 0x00 },
0248 { STB0899_UPKTERRORL , 0x00 },
0249 { 0xffff , 0xff },
0250 };
0251
0252
0253
0254 static struct stb0899_config az6027_stb0899_config = {
0255 .init_dev = az6027_stb0899_s1_init_1,
0256 .init_s2_demod = stb0899_s2_init_2,
0257 .init_s1_demod = az6027_stb0899_s1_init_3,
0258 .init_s2_fec = stb0899_s2_init_4,
0259 .init_tst = stb0899_s1_init_5,
0260
0261 .demod_address = 0xd0,
0262
0263 .xtal_freq = 27000000,
0264 .inversion = IQ_SWAP_ON,
0265
0266 .lo_clk = 76500000,
0267 .hi_clk = 99000000,
0268
0269 .esno_ave = STB0899_DVBS2_ESNO_AVE,
0270 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
0271 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
0272 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
0273 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
0274 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
0275 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
0276 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
0277 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
0278
0279 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
0280 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
0281 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
0282 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
0283
0284 .tuner_get_frequency = stb6100_get_frequency,
0285 .tuner_set_frequency = stb6100_set_frequency,
0286 .tuner_set_bandwidth = stb6100_set_bandwidth,
0287 .tuner_get_bandwidth = stb6100_get_bandwidth,
0288 .tuner_set_rfsiggain = NULL,
0289 };
0290
0291 static struct stb6100_config az6027_stb6100_config = {
0292 .tuner_address = 0xc0,
0293 .refclock = 27000000,
0294 };
0295
0296
0297
0298 static int az6027_usb_in_op(struct dvb_usb_device *d, u8 req,
0299 u16 value, u16 index, u8 *b, int blen)
0300 {
0301 int ret = -1;
0302 if (mutex_lock_interruptible(&d->usb_mutex))
0303 return -EAGAIN;
0304
0305 ret = usb_control_msg(d->udev,
0306 usb_rcvctrlpipe(d->udev, 0),
0307 req,
0308 USB_TYPE_VENDOR | USB_DIR_IN,
0309 value,
0310 index,
0311 b,
0312 blen,
0313 2000);
0314
0315 if (ret < 0) {
0316 warn("usb in operation failed. (%d)", ret);
0317 ret = -EIO;
0318 } else
0319 ret = 0;
0320
0321 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
0322 debug_dump(b, blen, deb_xfer);
0323
0324 mutex_unlock(&d->usb_mutex);
0325 return ret;
0326 }
0327
0328 static int az6027_usb_out_op(struct dvb_usb_device *d,
0329 u8 req,
0330 u16 value,
0331 u16 index,
0332 u8 *b,
0333 int blen)
0334 {
0335 int ret;
0336
0337 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
0338 debug_dump(b, blen, deb_xfer);
0339
0340 if (mutex_lock_interruptible(&d->usb_mutex))
0341 return -EAGAIN;
0342
0343 ret = usb_control_msg(d->udev,
0344 usb_sndctrlpipe(d->udev, 0),
0345 req,
0346 USB_TYPE_VENDOR | USB_DIR_OUT,
0347 value,
0348 index,
0349 b,
0350 blen,
0351 2000);
0352
0353 if (ret != blen) {
0354 warn("usb out operation failed. (%d)", ret);
0355 mutex_unlock(&d->usb_mutex);
0356 return -EIO;
0357 } else{
0358 mutex_unlock(&d->usb_mutex);
0359 return 0;
0360 }
0361 }
0362
0363 static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
0364 {
0365 int ret;
0366 u8 req;
0367 u16 value;
0368 u16 index;
0369 int blen;
0370
0371 deb_info("%s %d", __func__, onoff);
0372
0373 req = 0xBC;
0374 value = onoff;
0375 index = 0;
0376 blen = 0;
0377
0378 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0379 if (ret != 0)
0380 warn("usb out operation failed. (%d)", ret);
0381
0382 return ret;
0383 }
0384
0385
0386 static struct rc_map_table rc_map_az6027_table[] = {
0387 { 0x01, KEY_1 },
0388 { 0x02, KEY_2 },
0389 };
0390
0391
0392 static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
0393 {
0394 *state = REMOTE_NO_KEY_PRESSED;
0395 return 0;
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
0407 int slot,
0408 int address)
0409 {
0410 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0411 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0412
0413 int ret;
0414 u8 req;
0415 u16 value;
0416 u16 index;
0417 int blen;
0418 u8 *b;
0419
0420 if (slot != 0)
0421 return -EINVAL;
0422
0423 b = kmalloc(12, GFP_KERNEL);
0424 if (!b)
0425 return -ENOMEM;
0426
0427 mutex_lock(&state->ca_mutex);
0428
0429 req = 0xC1;
0430 value = address;
0431 index = 0;
0432 blen = 1;
0433
0434 ret = az6027_usb_in_op(d, req, value, index, b, blen);
0435 if (ret < 0) {
0436 warn("usb in operation failed. (%d)", ret);
0437 ret = -EINVAL;
0438 } else {
0439 ret = b[0];
0440 }
0441
0442 mutex_unlock(&state->ca_mutex);
0443 kfree(b);
0444 return ret;
0445 }
0446
0447 static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
0448 int slot,
0449 int address,
0450 u8 value)
0451 {
0452 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0453 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0454
0455 int ret;
0456 u8 req;
0457 u16 value1;
0458 u16 index;
0459 int blen;
0460
0461 deb_info("%s %d", __func__, slot);
0462 if (slot != 0)
0463 return -EINVAL;
0464
0465 mutex_lock(&state->ca_mutex);
0466 req = 0xC2;
0467 value1 = address;
0468 index = value;
0469 blen = 0;
0470
0471 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
0472 if (ret != 0)
0473 warn("usb out operation failed. (%d)", ret);
0474
0475 mutex_unlock(&state->ca_mutex);
0476 return ret;
0477 }
0478
0479 static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
0480 int slot,
0481 u8 address)
0482 {
0483 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0484 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0485
0486 int ret;
0487 u8 req;
0488 u16 value;
0489 u16 index;
0490 int blen;
0491 u8 *b;
0492
0493 if (slot != 0)
0494 return -EINVAL;
0495
0496 b = kmalloc(12, GFP_KERNEL);
0497 if (!b)
0498 return -ENOMEM;
0499
0500 mutex_lock(&state->ca_mutex);
0501
0502 req = 0xC3;
0503 value = address;
0504 index = 0;
0505 blen = 2;
0506
0507 ret = az6027_usb_in_op(d, req, value, index, b, blen);
0508 if (ret < 0) {
0509 warn("usb in operation failed. (%d)", ret);
0510 ret = -EINVAL;
0511 } else {
0512 if (b[0] == 0)
0513 warn("Read CI IO error");
0514
0515 ret = b[1];
0516 deb_info("read cam data = %x from 0x%x", b[1], value);
0517 }
0518
0519 mutex_unlock(&state->ca_mutex);
0520 kfree(b);
0521 return ret;
0522 }
0523
0524 static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
0525 int slot,
0526 u8 address,
0527 u8 value)
0528 {
0529 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0530 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0531
0532 int ret;
0533 u8 req;
0534 u16 value1;
0535 u16 index;
0536 int blen;
0537
0538 if (slot != 0)
0539 return -EINVAL;
0540
0541 mutex_lock(&state->ca_mutex);
0542 req = 0xC4;
0543 value1 = address;
0544 index = value;
0545 blen = 0;
0546
0547 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
0548 if (ret != 0) {
0549 warn("usb out operation failed. (%d)", ret);
0550 goto failed;
0551 }
0552
0553 failed:
0554 mutex_unlock(&state->ca_mutex);
0555 return ret;
0556 }
0557
0558 static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
0559 {
0560 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0561
0562 int ret;
0563 u8 req;
0564 u16 value;
0565 u16 index;
0566 int blen;
0567 u8 *b;
0568
0569 b = kmalloc(12, GFP_KERNEL);
0570 if (!b)
0571 return -ENOMEM;
0572
0573 req = 0xC8;
0574 value = 0;
0575 index = 0;
0576 blen = 1;
0577
0578 ret = az6027_usb_in_op(d, req, value, index, b, blen);
0579 if (ret < 0) {
0580 warn("usb in operation failed. (%d)", ret);
0581 ret = -EIO;
0582 } else{
0583 ret = b[0];
0584 }
0585 kfree(b);
0586 return ret;
0587 }
0588
0589 static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
0590 {
0591 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0592 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0593
0594 int ret, i;
0595 u8 req;
0596 u16 value;
0597 u16 index;
0598 int blen;
0599
0600 mutex_lock(&state->ca_mutex);
0601
0602 req = 0xC6;
0603 value = 1;
0604 index = 0;
0605 blen = 0;
0606
0607 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
0608 if (ret != 0) {
0609 warn("usb out operation failed. (%d)", ret);
0610 goto failed;
0611 }
0612
0613 msleep(500);
0614 req = 0xC6;
0615 value = 0;
0616 index = 0;
0617 blen = 0;
0618
0619 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
0620 if (ret != 0) {
0621 warn("usb out operation failed. (%d)", ret);
0622 goto failed;
0623 }
0624
0625 for (i = 0; i < 15; i++) {
0626 msleep(100);
0627
0628 if (CI_CamReady(ca, slot)) {
0629 deb_info("CAM Ready");
0630 break;
0631 }
0632 }
0633 msleep(5000);
0634
0635 failed:
0636 mutex_unlock(&state->ca_mutex);
0637 return ret;
0638 }
0639
0640 static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
0641 {
0642 return 0;
0643 }
0644
0645 static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
0646 {
0647 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0648 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0649
0650 int ret;
0651 u8 req;
0652 u16 value;
0653 u16 index;
0654 int blen;
0655
0656 deb_info("%s", __func__);
0657 mutex_lock(&state->ca_mutex);
0658 req = 0xC7;
0659 value = 1;
0660 index = 0;
0661 blen = 0;
0662
0663 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
0664 if (ret != 0) {
0665 warn("usb out operation failed. (%d)", ret);
0666 goto failed;
0667 }
0668
0669 failed:
0670 mutex_unlock(&state->ca_mutex);
0671 return ret;
0672 }
0673
0674 static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
0675 {
0676 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
0677 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0678 int ret;
0679 u8 req;
0680 u16 value;
0681 u16 index;
0682 int blen;
0683 u8 *b;
0684
0685 b = kmalloc(12, GFP_KERNEL);
0686 if (!b)
0687 return -ENOMEM;
0688 mutex_lock(&state->ca_mutex);
0689
0690 req = 0xC5;
0691 value = 0;
0692 index = 0;
0693 blen = 1;
0694
0695 ret = az6027_usb_in_op(d, req, value, index, b, blen);
0696 if (ret < 0) {
0697 warn("usb in operation failed. (%d)", ret);
0698 ret = -EIO;
0699 } else
0700 ret = 0;
0701
0702 if (!ret && b[0] == 1) {
0703 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
0704 DVB_CA_EN50221_POLL_CAM_READY;
0705 }
0706
0707 mutex_unlock(&state->ca_mutex);
0708 kfree(b);
0709 return ret;
0710 }
0711
0712
0713 static void az6027_ci_uninit(struct dvb_usb_device *d)
0714 {
0715 struct az6027_device_state *state;
0716
0717 deb_info("%s", __func__);
0718
0719 if (NULL == d)
0720 return;
0721
0722 state = (struct az6027_device_state *)d->priv;
0723 if (NULL == state)
0724 return;
0725
0726 if (NULL == state->ca.data)
0727 return;
0728
0729 dvb_ca_en50221_release(&state->ca);
0730
0731 memset(&state->ca, 0, sizeof(state->ca));
0732 }
0733
0734
0735 static int az6027_ci_init(struct dvb_usb_adapter *a)
0736 {
0737 struct dvb_usb_device *d = a->dev;
0738 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
0739 int ret;
0740
0741 deb_info("%s", __func__);
0742
0743 mutex_init(&state->ca_mutex);
0744
0745 state->ca.owner = THIS_MODULE;
0746 state->ca.read_attribute_mem = az6027_ci_read_attribute_mem;
0747 state->ca.write_attribute_mem = az6027_ci_write_attribute_mem;
0748 state->ca.read_cam_control = az6027_ci_read_cam_control;
0749 state->ca.write_cam_control = az6027_ci_write_cam_control;
0750 state->ca.slot_reset = az6027_ci_slot_reset;
0751 state->ca.slot_shutdown = az6027_ci_slot_shutdown;
0752 state->ca.slot_ts_enable = az6027_ci_slot_ts_enable;
0753 state->ca.poll_slot_status = az6027_ci_poll_slot_status;
0754 state->ca.data = d;
0755
0756 ret = dvb_ca_en50221_init(&a->dvb_adap,
0757 &state->ca,
0758 0,
0759 1);
0760 if (ret != 0) {
0761 err("Cannot initialize CI: Error %d.", ret);
0762 memset(&state->ca, 0, sizeof(state->ca));
0763 return ret;
0764 }
0765
0766 deb_info("CI initialized.");
0767
0768 return 0;
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779 static int az6027_set_voltage(struct dvb_frontend *fe,
0780 enum fe_sec_voltage voltage)
0781 {
0782
0783 u8 buf;
0784 struct dvb_usb_adapter *adap = fe->dvb->priv;
0785
0786 struct i2c_msg i2c_msg = {
0787 .addr = 0x99,
0788 .flags = 0,
0789 .buf = &buf,
0790 .len = 1
0791 };
0792
0793
0794
0795
0796
0797
0798 switch (voltage) {
0799 case SEC_VOLTAGE_13:
0800 buf = 1;
0801 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
0802 break;
0803
0804 case SEC_VOLTAGE_18:
0805 buf = 2;
0806 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
0807 break;
0808
0809 case SEC_VOLTAGE_OFF:
0810 buf = 0;
0811 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
0812 break;
0813
0814 default:
0815 return -EINVAL;
0816 }
0817 return 0;
0818 }
0819
0820
0821 static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
0822 {
0823 int ret;
0824 u8 req;
0825 u16 value;
0826 u16 index;
0827 int blen;
0828
0829 req = 0xBC;
0830 value = 1;
0831 index = 3;
0832 blen = 0;
0833
0834 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0835 if (ret != 0)
0836 return -EIO;
0837
0838 return 0;
0839 }
0840 static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
0841 {
0842 int ret;
0843 u8 req;
0844 u16 value;
0845 u16 index;
0846 int blen;
0847
0848
0849 req = 0xC0;
0850 value = 1;
0851 index = 3;
0852 blen = 0;
0853
0854 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0855 if (ret != 0)
0856 return -EIO;
0857
0858 req = 0xC0;
0859 value = 0;
0860 index = 3;
0861 blen = 0;
0862 msleep_interruptible(200);
0863
0864 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0865 if (ret != 0)
0866 return -EIO;
0867
0868 msleep_interruptible(200);
0869
0870 req = 0xC0;
0871 value = 1;
0872 index = 3;
0873 blen = 0;
0874
0875 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0876 if (ret != 0)
0877 return -EIO;
0878
0879 msleep_interruptible(200);
0880 return 0;
0881 }
0882
0883 static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
0884 {
0885 int ret;
0886 u8 req;
0887 u16 value;
0888 u16 index;
0889 int blen;
0890
0891
0892 req = 0xC7;
0893 value = onoff;
0894 index = 0;
0895 blen = 0;
0896
0897 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
0898 if (ret != 0)
0899 return -EIO;
0900
0901 return 0;
0902 }
0903
0904 static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
0905 {
0906
0907 az6027_frontend_poweron(adap);
0908 az6027_frontend_reset(adap);
0909
0910 deb_info("adap = %p, dev = %p\n", adap, adap->dev);
0911 adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
0912
0913 if (adap->fe_adap[0].fe) {
0914 deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
0915 if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
0916 deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
0917 adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage;
0918 az6027_ci_init(adap);
0919 } else {
0920 adap->fe_adap[0].fe = NULL;
0921 }
0922 } else
0923 warn("no front-end attached\n");
0924
0925 az6027_frontend_tsbypass(adap, 0);
0926
0927 return 0;
0928 }
0929
0930 static struct dvb_usb_device_properties az6027_properties;
0931
0932 static void az6027_usb_disconnect(struct usb_interface *intf)
0933 {
0934 struct dvb_usb_device *d = usb_get_intfdata(intf);
0935 az6027_ci_uninit(d);
0936 dvb_usb_device_exit(intf);
0937 }
0938
0939
0940 static int az6027_usb_probe(struct usb_interface *intf,
0941 const struct usb_device_id *id)
0942 {
0943 return dvb_usb_device_init(intf,
0944 &az6027_properties,
0945 THIS_MODULE,
0946 NULL,
0947 adapter_nr);
0948 }
0949
0950
0951 static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
0952 {
0953 struct dvb_usb_device *d = i2c_get_adapdata(adap);
0954 int i = 0, j = 0, len = 0;
0955 u16 index;
0956 u16 value;
0957 int length;
0958 u8 req;
0959 u8 *data;
0960
0961 data = kmalloc(256, GFP_KERNEL);
0962 if (!data)
0963 return -ENOMEM;
0964
0965 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
0966 kfree(data);
0967 return -EAGAIN;
0968 }
0969
0970 if (num > 2)
0971 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
0972
0973 for (i = 0; i < num; i++) {
0974
0975 if (msg[i].addr == 0x99) {
0976 req = 0xBE;
0977 index = 0;
0978 value = msg[i].buf[0] & 0x00ff;
0979 length = 1;
0980 az6027_usb_out_op(d, req, value, index, data, length);
0981 }
0982
0983 if (msg[i].addr == 0xd0) {
0984
0985 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
0986 req = 0xB9;
0987 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
0988 value = msg[i].addr + (msg[i].len << 8);
0989 length = msg[i + 1].len + 6;
0990 az6027_usb_in_op(d, req, value, index, data, length);
0991 len = msg[i + 1].len;
0992 for (j = 0; j < len; j++)
0993 msg[i + 1].buf[j] = data[j + 5];
0994
0995 i++;
0996 } else {
0997
0998
0999 req = 0xBD;
1000 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
1001 value = msg[i].addr + (2 << 8);
1002 length = msg[i].len - 2;
1003 len = msg[i].len - 2;
1004 for (j = 0; j < len; j++)
1005 data[j] = msg[i].buf[j + 2];
1006 az6027_usb_out_op(d, req, value, index, data, length);
1007 }
1008 }
1009
1010 if (msg[i].addr == 0xc0) {
1011 if (msg[i].flags & I2C_M_RD) {
1012
1013 req = 0xB9;
1014 index = 0x0;
1015 value = msg[i].addr;
1016 length = msg[i].len + 6;
1017 az6027_usb_in_op(d, req, value, index, data, length);
1018 len = msg[i].len;
1019 for (j = 0; j < len; j++)
1020 msg[i].buf[j] = data[j + 5];
1021
1022 } else {
1023
1024 req = 0xBD;
1025 index = msg[i].buf[0] & 0x00FF;
1026 value = msg[i].addr + (1 << 8);
1027 length = msg[i].len - 1;
1028 len = msg[i].len - 1;
1029
1030 for (j = 0; j < len; j++)
1031 data[j] = msg[i].buf[j + 1];
1032
1033 az6027_usb_out_op(d, req, value, index, data, length);
1034 }
1035 }
1036 }
1037 mutex_unlock(&d->i2c_mutex);
1038 kfree(data);
1039
1040 return i;
1041 }
1042
1043
1044 static u32 az6027_i2c_func(struct i2c_adapter *adapter)
1045 {
1046 return I2C_FUNC_I2C;
1047 }
1048
1049 static struct i2c_algorithm az6027_i2c_algo = {
1050 .master_xfer = az6027_i2c_xfer,
1051 .functionality = az6027_i2c_func,
1052 };
1053
1054 static int az6027_identify_state(struct usb_device *udev,
1055 const struct dvb_usb_device_properties *props,
1056 const struct dvb_usb_device_description **desc,
1057 int *cold)
1058 {
1059 u8 *b;
1060 s16 ret;
1061
1062 b = kmalloc(16, GFP_KERNEL);
1063 if (!b)
1064 return -ENOMEM;
1065
1066 ret = usb_control_msg(udev,
1067 usb_rcvctrlpipe(udev, 0),
1068 0xb7,
1069 USB_TYPE_VENDOR | USB_DIR_IN,
1070 6,
1071 0,
1072 b,
1073 6,
1074 USB_CTRL_GET_TIMEOUT);
1075
1076 *cold = ret <= 0;
1077 kfree(b);
1078 deb_info("cold: %d\n", *cold);
1079 return 0;
1080 }
1081
1082
1083 enum {
1084 AZUREWAVE_AZ6027,
1085 TERRATEC_DVBS2CI_V1,
1086 TERRATEC_DVBS2CI_V2,
1087 TECHNISAT_USB2_HDCI_V1,
1088 TECHNISAT_USB2_HDCI_V2,
1089 ELGATO_EYETV_SAT,
1090 ELGATO_EYETV_SAT_V2,
1091 ELGATO_EYETV_SAT_V3,
1092 };
1093
1094 static struct usb_device_id az6027_usb_table[] = {
1095 DVB_USB_DEV(AZUREWAVE, AZUREWAVE_AZ6027),
1096 DVB_USB_DEV(TERRATEC, TERRATEC_DVBS2CI_V1),
1097 DVB_USB_DEV(TERRATEC, TERRATEC_DVBS2CI_V2),
1098 DVB_USB_DEV(TECHNISAT, TECHNISAT_USB2_HDCI_V1),
1099 DVB_USB_DEV(TECHNISAT, TECHNISAT_USB2_HDCI_V2),
1100 DVB_USB_DEV(ELGATO, ELGATO_EYETV_SAT),
1101 DVB_USB_DEV(ELGATO, ELGATO_EYETV_SAT_V2),
1102 DVB_USB_DEV(ELGATO, ELGATO_EYETV_SAT_V3),
1103 { }
1104 };
1105
1106 MODULE_DEVICE_TABLE(usb, az6027_usb_table);
1107
1108 static struct dvb_usb_device_properties az6027_properties = {
1109 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1110 .usb_ctrl = CYPRESS_FX2,
1111 .firmware = "dvb-usb-az6027-03.fw",
1112 .no_reconnect = 1,
1113
1114 .size_of_priv = sizeof(struct az6027_device_state),
1115 .identify_state = az6027_identify_state,
1116 .num_adapters = 1,
1117 .adapter = {
1118 {
1119 .num_frontends = 1,
1120 .fe = {{
1121 .streaming_ctrl = az6027_streaming_ctrl,
1122 .frontend_attach = az6027_frontend_attach,
1123
1124
1125 .stream = {
1126 .type = USB_BULK,
1127 .count = 10,
1128 .endpoint = 0x02,
1129 .u = {
1130 .bulk = {
1131 .buffersize = 4096,
1132 }
1133 }
1134 },
1135 }},
1136 }
1137 },
1138
1139
1140
1141
1142 .rc.legacy = {
1143 .rc_map_table = rc_map_az6027_table,
1144 .rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
1145 .rc_interval = 400,
1146 .rc_query = az6027_rc_query,
1147 },
1148
1149 .i2c_algo = &az6027_i2c_algo,
1150
1151 .num_device_descs = 8,
1152 .devices = {
1153 {
1154 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
1155 .cold_ids = { &az6027_usb_table[AZUREWAVE_AZ6027], NULL },
1156 .warm_ids = { NULL },
1157 }, {
1158 .name = "TERRATEC S7",
1159 .cold_ids = { &az6027_usb_table[TERRATEC_DVBS2CI_V1], NULL },
1160 .warm_ids = { NULL },
1161 }, {
1162 .name = "TERRATEC S7 MKII",
1163 .cold_ids = { &az6027_usb_table[TERRATEC_DVBS2CI_V2], NULL },
1164 .warm_ids = { NULL },
1165 }, {
1166 .name = "Technisat SkyStar USB 2 HD CI",
1167 .cold_ids = { &az6027_usb_table[TECHNISAT_USB2_HDCI_V1], NULL },
1168 .warm_ids = { NULL },
1169 }, {
1170 .name = "Technisat SkyStar USB 2 HD CI",
1171 .cold_ids = { &az6027_usb_table[TECHNISAT_USB2_HDCI_V2], NULL },
1172 .warm_ids = { NULL },
1173 }, {
1174 .name = "Elgato EyeTV Sat",
1175 .cold_ids = { &az6027_usb_table[ELGATO_EYETV_SAT], NULL },
1176 .warm_ids = { NULL },
1177 }, {
1178 .name = "Elgato EyeTV Sat",
1179 .cold_ids = { &az6027_usb_table[ELGATO_EYETV_SAT_V2], NULL },
1180 .warm_ids = { NULL },
1181 }, {
1182 .name = "Elgato EyeTV Sat",
1183 .cold_ids = { &az6027_usb_table[ELGATO_EYETV_SAT_V3], NULL },
1184 .warm_ids = { NULL },
1185 },
1186 { NULL },
1187 }
1188 };
1189
1190
1191 static struct usb_driver az6027_usb_driver = {
1192 .name = "dvb_usb_az6027",
1193 .probe = az6027_usb_probe,
1194 .disconnect = az6027_usb_disconnect,
1195 .id_table = az6027_usb_table,
1196 };
1197
1198 module_usb_driver(az6027_usb_driver);
1199
1200 MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
1201 MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
1202 MODULE_VERSION("1.0");
1203 MODULE_LICENSE("GPL");