static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct ec168_req req; int i = 0; int ret; if (num > 2) return -EINVAL; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; while (i < num) { if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (msg[i].addr == ec168_ec100_config.demod_address) { req.cmd = READ_DEMOD; req.value = 0; req.index = 0xff00 + msg[i].buf[0]; /* reg */ req.size = msg[i+1].len; /* bytes to read */ req.data = &msg[i+1].buf[0]; ret = ec168_ctrl_msg(d, &req); i += 2; } else { dev_err(&d->udev->dev, "%s: I2C read not " \ "implemented\n", KBUILD_MODNAME); ret = -EOPNOTSUPP; i += 2; } } else { if (msg[i].addr == ec168_ec100_config.demod_address) { req.cmd = WRITE_DEMOD; req.value = msg[i].buf[1]; /* val */ req.index = 0xff00 + msg[i].buf[0]; /* reg */ req.size = 0; req.data = NULL; ret = ec168_ctrl_msg(d, &req); i += 1; } else { req.cmd = WRITE_I2C; req.value = msg[i].buf[0]; /* val */ req.index = 0x0100 + msg[i].addr; /* I2C addr */ req.size = msg[i].len-1; req.data = &msg[i].buf[1]; ret = ec168_ctrl_msg(d, &req); i += 1; } } if (ret) goto error; } ret = i; error: mutex_unlock(&d->i2c_mutex); return ret; }
static int ec168_download_firmware(struct dvb_usb_device *d, const struct firmware *fw) { int ret, len, remaining; struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL}; dev_dbg(&d->udev->dev, "%s:\n", __func__); #define LEN_MAX 2048 /* max packet size */ for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { len = remaining; if (len > LEN_MAX) len = LEN_MAX; req.size = len; req.data = (u8 *) &fw->data[fw->size - remaining]; req.index = fw->size - remaining; ret = ec168_ctrl_msg(d, &req); if (ret) { dev_err(&d->udev->dev, "%s: firmware download failed=%d\n", KBUILD_MODNAME, ret); goto error; } } req.size = 0; /* set "warm"? */ req.cmd = SET_CONFIG; req.value = 0; req.index = 0x0001; ret = ec168_ctrl_msg(d, &req); if (ret) goto error; /* really needed - no idea what does */ req.cmd = GPIO; req.value = 0; req.index = 0x0206; ret = ec168_ctrl_msg(d, &req); if (ret) goto error; /* activate tuner I2C? */ req.cmd = WRITE_I2C; req.value = 0; req.index = 0x00c6; ret = ec168_ctrl_msg(d, &req); if (ret) goto error; return ret; error: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; }
static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL}; deb_info("%s: onoff:%d\n", __func__, onoff); if (onoff) req.index = 0x0102; return ec168_ctrl_msg(adap->dev, &req); }
static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff) { struct dvb_usb_device *d = fe_to_d(fe); struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL}; dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff); if (onoff) req.index = 0x0102; return ec168_ctrl_msg(d, &req); }
/* Callbacks for DVB USB */ static int ec168_identify_state(struct dvb_usb_device *d, const char **name) { int ret; u8 reply; struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply}; dev_dbg(&d->udev->dev, "%s:\n", __func__); ret = ec168_ctrl_msg(d, &req); if (ret) goto error; dev_dbg(&d->udev->dev, "%s: reply=%02x\n", __func__, reply); if (reply == 0x01) ret = WARM; else ret = COLD; return ret; error: dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); return ret; }