1/* 2 * E3C EC168 DVB USB driver 3 * 4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 */ 21 22#include "ec168.h" 23#include "ec100.h" 24#include "mxl5005s.h" 25 26/* debug */ 27static int dvb_usb_ec168_debug; 28module_param_named(debug, dvb_usb_ec168_debug, int, 0644); 29MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); 30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 31 32static struct ec100_config ec168_ec100_config; 33 34static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req) 35{ 36 int ret; 37 unsigned int pipe; 38 u8 request, requesttype; 39 u8 buf[req->size]; 40 41 switch (req->cmd) { 42 case DOWNLOAD_FIRMWARE: 43 case GPIO: 44 case WRITE_I2C: 45 case STREAMING_CTRL: 46 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); 47 request = req->cmd; 48 break; 49 case READ_I2C: 50 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); 51 request = req->cmd; 52 break; 53 case GET_CONFIG: 54 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); 55 request = CONFIG; 56 break; 57 case SET_CONFIG: 58 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); 59 request = CONFIG; 60 break; 61 case WRITE_DEMOD: 62 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); 63 request = DEMOD_RW; 64 break; 65 case READ_DEMOD: 66 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); 67 request = DEMOD_RW; 68 break; 69 default: 70 err("unknown command:%02x", req->cmd); 71 ret = -EPERM; 72 goto error; 73 } 74 75 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) { 76 /* write */ 77 memcpy(buf, req->data, req->size); 78 pipe = usb_sndctrlpipe(udev, 0); 79 } else { 80 /* read */ 81 pipe = usb_rcvctrlpipe(udev, 0); 82 } 83 84 msleep(1); /* avoid I2C errors */ 85 86 ret = usb_control_msg(udev, pipe, request, requesttype, req->value, 87 req->index, buf, sizeof(buf), EC168_USB_TIMEOUT); 88 89 ec168_debug_dump(request, requesttype, req->value, req->index, buf, 90 req->size, deb_xfer); 91 92 if (ret < 0) 93 goto error; 94 else 95 ret = 0; 96 97 /* read request, copy returned data to return buf */ 98 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) 99 memcpy(req->data, buf, req->size); 100 101 return ret; 102error: 103 deb_info("%s: failed:%d\n", __func__, ret); 104 return ret; 105} 106 107static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req) 108{ 109 return ec168_rw_udev(d->udev, req); 110} 111 112/* I2C */ 113static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 114 int num) 115{ 116 struct dvb_usb_device *d = i2c_get_adapdata(adap); 117 struct ec168_req req; 118 int i = 0; 119 int ret; 120 121 if (num > 2) 122 return -EINVAL; 123 124 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) 125 return -EAGAIN; 126 127 while (i < num) { 128 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { 129 if (msg[i].addr == ec168_ec100_config.demod_address) { 130 req.cmd = READ_DEMOD; 131 req.value = 0; 132 req.index = 0xff00 + msg[i].buf[0]; /* reg */ 133 req.size = msg[i+1].len; /* bytes to read */ 134 req.data = &msg[i+1].buf[0]; 135 ret = ec168_ctrl_msg(d, &req); 136 i += 2; 137 } else { 138 err("I2C read not implemented"); 139 ret = -ENOSYS; 140 i += 2; 141 } 142 } else { 143 if (msg[i].addr == ec168_ec100_config.demod_address) { 144 req.cmd = WRITE_DEMOD; 145 req.value = msg[i].buf[1]; /* val */ 146 req.index = 0xff00 + msg[i].buf[0]; /* reg */ 147 req.size = 0; 148 req.data = NULL; 149 ret = ec168_ctrl_msg(d, &req); 150 i += 1; 151 } else { 152 req.cmd = WRITE_I2C; 153 req.value = msg[i].buf[0]; /* val */ 154 req.index = 0x0100 + msg[i].addr; /* I2C addr */ 155 req.size = msg[i].len-1; 156 req.data = &msg[i].buf[1]; 157 ret = ec168_ctrl_msg(d, &req); 158 i += 1; 159 } 160 } 161 if (ret) 162 goto error; 163 164 } 165 ret = i; 166 167error: 168 mutex_unlock(&d->i2c_mutex); 169 return i; 170} 171 172 173static u32 ec168_i2c_func(struct i2c_adapter *adapter) 174{ 175 return I2C_FUNC_I2C; 176} 177 178static struct i2c_algorithm ec168_i2c_algo = { 179 .master_xfer = ec168_i2c_xfer, 180 .functionality = ec168_i2c_func, 181}; 182 183/* Callbacks for DVB USB */ 184static struct ec100_config ec168_ec100_config = { 185 .demod_address = 0xff, /* not real address, demod is integrated */ 186}; 187 188static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap) 189{ 190 deb_info("%s:\n", __func__); 191 adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config, 192 &adap->dev->i2c_adap); 193 if (adap->fe == NULL) 194 return -ENODEV; 195 196 return 0; 197} 198 199static struct mxl5005s_config ec168_mxl5003s_config = { 200 .i2c_address = 0xc6, 201 .if_freq = IF_FREQ_4570000HZ, 202 .xtal_freq = CRYSTAL_FREQ_16000000HZ, 203 .agc_mode = MXL_SINGLE_AGC, 204 .tracking_filter = MXL_TF_OFF, 205 .rssi_enable = MXL_RSSI_ENABLE, 206 .cap_select = MXL_CAP_SEL_ENABLE, 207 .div_out = MXL_DIV_OUT_4, 208 .clock_out = MXL_CLOCK_OUT_DISABLE, 209 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, 210 .top = MXL5005S_TOP_25P2, 211 .mod_mode = MXL_DIGITAL_MODE, 212 .if_mode = MXL_ZERO_IF, 213 .AgcMasterByte = 0x00, 214}; 215 216static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) 217{ 218 deb_info("%s:\n", __func__); 219 return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, 220 &ec168_mxl5003s_config) == NULL ? -ENODEV : 0; 221} 222 223static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 224{ 225 struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL}; 226 deb_info("%s: onoff:%d\n", __func__, onoff); 227 if (onoff) 228 req.index = 0x0102; 229 return ec168_ctrl_msg(adap->dev, &req); 230} 231 232static int ec168_download_firmware(struct usb_device *udev, 233 const struct firmware *fw) 234{ 235 int i, len, packets, remainder, ret; 236 u16 addr = 0x0000; /* firmware start address */ 237 struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL}; 238 deb_info("%s:\n", __func__); 239 240 #define FW_PACKET_MAX_DATA 2048 241 packets = fw->size / FW_PACKET_MAX_DATA; 242 remainder = fw->size % FW_PACKET_MAX_DATA; 243 len = FW_PACKET_MAX_DATA; 244 for (i = 0; i <= packets; i++) { 245 if (i == packets) /* set size of the last packet */ 246 len = remainder; 247 248 req.size = len; 249 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); 250 req.index = addr; 251 addr += FW_PACKET_MAX_DATA; 252 253 ret = ec168_rw_udev(udev, &req); 254 if (ret) { 255 err("firmware download failed:%d packet:%d", ret, i); 256 goto error; 257 } 258 } 259 req.size = 0; 260 261 /* set "warm"? */ 262 req.cmd = SET_CONFIG; 263 req.value = 0; 264 req.index = 0x0001; 265 ret = ec168_rw_udev(udev, &req); 266 if (ret) 267 goto error; 268 269 /* really needed - no idea what does */ 270 req.cmd = GPIO; 271 req.value = 0; 272 req.index = 0x0206; 273 ret = ec168_rw_udev(udev, &req); 274 if (ret) 275 goto error; 276 277 /* activate tuner I2C? */ 278 req.cmd = WRITE_I2C; 279 req.value = 0; 280 req.index = 0x00c6; 281 ret = ec168_rw_udev(udev, &req); 282 if (ret) 283 goto error; 284 285 return ret; 286error: 287 deb_info("%s: failed:%d\n", __func__, ret); 288 return ret; 289} 290 291static int ec168_identify_state(struct usb_device *udev, 292 struct dvb_usb_device_properties *props, 293 struct dvb_usb_device_description **desc, int *cold) 294{ 295 int ret; 296 u8 reply; 297 struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply}; 298 deb_info("%s:\n", __func__); 299 300 ret = ec168_rw_udev(udev, &req); 301 if (ret) 302 goto error; 303 304 deb_info("%s: reply:%02x\n", __func__, reply); 305 306 if (reply == 0x01) 307 *cold = 0; 308 else 309 *cold = 1; 310 311 return ret; 312error: 313 deb_info("%s: failed:%d\n", __func__, ret); 314 return ret; 315} 316 317/* DVB USB Driver stuff */ 318static struct dvb_usb_device_properties ec168_properties; 319 320static int ec168_probe(struct usb_interface *intf, 321 const struct usb_device_id *id) 322{ 323 int ret; 324 deb_info("%s: interface:%d\n", __func__, 325 intf->cur_altsetting->desc.bInterfaceNumber); 326 327 ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL, 328 adapter_nr); 329 if (ret) 330 goto error; 331 332 return ret; 333error: 334 deb_info("%s: failed:%d\n", __func__, ret); 335 return ret; 336} 337 338#define E3C_EC168_1689 0 339#define E3C_EC168_FFFA 1 340#define E3C_EC168_FFFB 2 341#define E3C_EC168_1001 3 342#define E3C_EC168_1002 4 343 344static struct usb_device_id ec168_id[] = { 345 [E3C_EC168_1689] = 346 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)}, 347 [E3C_EC168_FFFA] = 348 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)}, 349 [E3C_EC168_FFFB] = 350 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)}, 351 [E3C_EC168_1001] = 352 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)}, 353 [E3C_EC168_1002] = 354 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)}, 355 {} /* terminating entry */ 356}; 357 358MODULE_DEVICE_TABLE(usb, ec168_id); 359 360static struct dvb_usb_device_properties ec168_properties = { 361 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 362 363 .usb_ctrl = DEVICE_SPECIFIC, 364 .download_firmware = ec168_download_firmware, 365 .firmware = "dvb-usb-ec168.fw", 366 .no_reconnect = 1, 367 368 .size_of_priv = 0, 369 370 .num_adapters = 1, 371 .adapter = { 372 { 373 .streaming_ctrl = ec168_streaming_ctrl, 374 .frontend_attach = ec168_ec100_frontend_attach, 375 .tuner_attach = ec168_mxl5003s_tuner_attach, 376 .stream = { 377 .type = USB_BULK, 378 .count = 6, 379 .endpoint = 0x82, 380 .u = { 381 .bulk = { 382 .buffersize = (32*512), 383 } 384 } 385 }, 386 } 387 }, 388 389 .identify_state = ec168_identify_state, 390 391 .i2c_algo = &ec168_i2c_algo, 392 393 .num_device_descs = 1, 394 .devices = { 395 { 396 .name = "E3C EC168 DVB-T USB2.0 reference design", 397 .cold_ids = { 398 &ec168_id[E3C_EC168_1689], 399 &ec168_id[E3C_EC168_FFFA], 400 &ec168_id[E3C_EC168_FFFB], 401 &ec168_id[E3C_EC168_1001], 402 &ec168_id[E3C_EC168_1002], 403 NULL}, 404 .warm_ids = {NULL}, 405 }, 406 } 407}; 408 409static struct usb_driver ec168_driver = { 410 .name = "dvb_usb_ec168", 411 .probe = ec168_probe, 412 .disconnect = dvb_usb_device_exit, 413 .id_table = ec168_id, 414}; 415 416/* module stuff */ 417static int __init ec168_module_init(void) 418{ 419 int ret; 420 deb_info("%s:\n", __func__); 421 ret = usb_register(&ec168_driver); 422 if (ret) 423 err("module init failed:%d", ret); 424 425 return ret; 426} 427 428static void __exit ec168_module_exit(void) 429{ 430 deb_info("%s:\n", __func__); 431 /* deregister this driver from the USB subsystem */ 432 usb_deregister(&ec168_driver); 433} 434 435module_init(ec168_module_init); 436module_exit(ec168_module_exit); 437 438MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 439MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver"); 440MODULE_LICENSE("GPL"); 441