1 /* DVB USB compliant linux driver for
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F
5 * LME2510 + LG TDQY-P001F
7 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
8 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
10 * MV001F (LME2510+LGTDQY-P001F)
11 * LG TDQY - P001F =(TDA8263 + TDA10086H)
13 * MVB0001F (LME2510C+LGTDQT-P001F)
15 * For firmware see Documentation/dvb/lmedm04.txt
18 * 0xd0 - STV0288 - Demodulator
19 * 0xc0 - Sharp IX2505V - Tuner
21 * 0x1c - TDA10086 - Demodulator
22 * 0xc0 - TDA8263 - Tuner
25 * There are other variants of the DM04
27 * MV0194 (LME2510+SHARP0194)
28 * MVB0194 (LME2510C+SHARP0194)
31 * VID = 3344 PID LME2510=1122 LME2510C=1120
33 * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
34 * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
36 * This program is free software; you can redistribute it and/or modify
37 * it under the terms of the GNU General Public License Version 2, as
38 * published by the Free Software Foundation.
40 * This program is distributed in the hope that it will be useful,
41 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 * GNU General Public License for more details.
45 * You should have received a copy of the GNU General Public License
46 * along with this program; if not, write to the Free Software
47 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
50 * see Documentation/dvb/README.dvb-usb for more information
53 * LME2510: Non Intel USB chipsets fail to maintain High Speed on
56 * QQbox suffers from noise on LNB voltage.
58 * PID functions have been removed from this driver version due to
59 * problems with different firmware and application versions.
61 #define DVB_USB_LOG_PREFIX "LME2510(C)"
62 #include <linux/usb.h>
63 #include <linux/usb/input.h>
64 #include <media/ir-core.h>
76 static int dvb_usb_lme2510_debug
;
77 #define l_dprintk(var, level, args...) do { \
79 printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
82 #define deb_info(level, args...) l_dprintk(dvb_usb_lme2510_debug, level, args)
83 #define debug_data_snipet(level, name, p) \
84 deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
85 *p, *(p+1), *(p+2), *(p+3), *(p+4), \
86 *(p+5), *(p+6), *(p+7));
89 module_param_named(debug
, dvb_usb_lme2510_debug
, int, 0644);
90 MODULE_PARM_DESC(debug
, "set debugging level (1=info (or-able))."
91 DVB_USB_DEBUG_STATUS
);
93 static int dvb_usb_lme2510_firmware
;
94 module_param_named(firmware
, dvb_usb_lme2510_firmware
, int, 0644);
95 MODULE_PARM_DESC(firmware
, "set default firmware 0=Sharp7395 1=LG");
98 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
100 #define TUNER_S7395 0x2
102 struct lme2510_state
{
122 static int lme2510_bulk_write(struct usb_device
*dev
,
123 u8
*snd
, int len
, u8 pipe
)
127 ret
= usb_bulk_msg(dev
, usb_sndbulkpipe(dev
, pipe
),
128 snd
, len
, &actual_l
, 500);
132 static int lme2510_bulk_read(struct usb_device
*dev
,
133 u8
*rev
, int len
, u8 pipe
)
137 ret
= usb_bulk_msg(dev
, usb_rcvbulkpipe(dev
, pipe
),
138 rev
, len
, &actual_l
, 500);
142 static int lme2510_usb_talk(struct dvb_usb_device
*d
,
143 u8
*wbuf
, int wlen
, u8
*rbuf
, int rlen
)
145 struct lme2510_state
*st
= d
->priv
;
149 if (st
->usb_buffer
== NULL
) {
150 st
->usb_buffer
= kmalloc(512, GFP_KERNEL
);
151 if (st
->usb_buffer
== NULL
) {
152 info("MEM Error no memory");
156 buff
= st
->usb_buffer
;
158 /* the read/write capped at 512 */
159 memcpy(buff
, wbuf
, (wlen
> 512) ? 512 : wlen
);
161 ret
= mutex_lock_interruptible(&d
->usb_mutex
);
166 ret
|= usb_clear_halt(d
->udev
, usb_sndbulkpipe(d
->udev
, 0x01));
168 ret
|= lme2510_bulk_write(d
->udev
, buff
, wlen
, 0x01);
172 ret
|= usb_clear_halt(d
->udev
, usb_rcvbulkpipe(d
->udev
, 0x01));
174 ret
|= lme2510_bulk_read(d
->udev
, buff
, (rlen
> 512) ?
178 memcpy(rbuf
, buff
, rlen
);
180 mutex_unlock(&d
->usb_mutex
);
182 return (ret
< 0) ? -ENODEV
: 0;
185 static int lme2510_usb_talk_restart(struct dvb_usb_device
*d
,
186 u8
*wbuf
, int wlen
, u8
*rbuf
, int rlen
) {
187 static u8 stream_on
[] = LME_ST_ON_W
;
190 /*Send Normal Command*/
191 ret
= lme2510_usb_talk(d
, wbuf
, wlen
, rbuf
, rlen
);
192 /*Restart Stream Command*/
193 ret
|= lme2510_usb_talk(d
, stream_on
, sizeof(stream_on
),
194 rbuff
, sizeof(rbuff
));
197 static int lme2510_remote_keypress(struct dvb_usb_adapter
*adap
, u16 keypress
)
199 struct dvb_usb_device
*d
= adap
->dev
;
201 deb_info(1, "INT Key Keypress =%04x", keypress
);
204 ir_keydown(d
->rc_input_dev
, keypress
, 0);
209 static void lme2510_int_response(struct urb
*lme_urb
)
211 struct dvb_usb_adapter
*adap
= lme_urb
->context
;
212 struct lme2510_state
*st
= adap
->dev
->priv
;
213 static u8
*ibuf
, *rbuf
;
216 switch (lme_urb
->status
) {
225 info("Error %x", lme_urb
->status
);
229 rbuf
= (u8
*) lme_urb
->transfer_buffer
;
231 offset
= ((lme_urb
->actual_length
/8) > 4)
232 ? 4 : (lme_urb
->actual_length
/8) ;
234 for (i
= 0; i
< offset
; ++i
) {
235 ibuf
= (u8
*)&rbuf
[i
*8];
236 deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
237 offset
, i
, ibuf
[0], ibuf
[1]);
241 debug_data_snipet(1, "INT Remote data snipet in", ibuf
);
242 lme2510_remote_keypress(adap
,
243 (u16
)(ibuf
[4]<<8)+ibuf
[5]);
246 switch (st
->tuner_config
) {
249 st
->signal_lock
= ibuf
[2];
250 st
->signal_level
= ibuf
[4];
251 st
->signal_sn
= ibuf
[3];
252 st
->time_key
= ibuf
[7];
255 /* Tweak for earlier firmware*/
256 if (ibuf
[1] == 0x03) {
257 st
->signal_level
= ibuf
[3];
258 st
->signal_sn
= ibuf
[4];
260 st
->signal_level
= ibuf
[4];
261 st
->signal_sn
= ibuf
[5];
267 debug_data_snipet(5, "INT Remote data snipet in", ibuf
);
270 debug_data_snipet(1, "INT Control data snipet", ibuf
);
273 debug_data_snipet(1, "INT Unknown data snipet", ibuf
);
277 usb_submit_urb(lme_urb
, GFP_ATOMIC
);
280 static int lme2510_int_read(struct dvb_usb_adapter
*adap
)
282 struct lme2510_state
*lme_int
= adap
->dev
->priv
;
284 lme_int
->lme_urb
= usb_alloc_urb(0, GFP_ATOMIC
);
286 if (lme_int
->lme_urb
== NULL
)
289 lme_int
->buffer
= usb_alloc_coherent(adap
->dev
->udev
, 5000, GFP_ATOMIC
,
290 &lme_int
->lme_urb
->transfer_dma
);
292 if (lme_int
->buffer
== NULL
)
295 usb_fill_int_urb(lme_int
->lme_urb
,
297 usb_rcvintpipe(adap
->dev
->udev
, 0xa),
300 lme2510_int_response
,
304 lme_int
->lme_urb
->transfer_flags
|= URB_NO_TRANSFER_DMA_MAP
;
306 usb_submit_urb(lme_int
->lme_urb
, GFP_ATOMIC
);
307 info("INT Interupt Service Started");
312 static int lme2510_return_status(struct usb_device
*dev
)
317 ret
|= usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
318 0x06, 0x80, 0x0302, 0x00, data
, 0x0006, 200);
319 info("Firmware Status: %x (%x)", ret
, data
[2]);
321 return (ret
< 0) ? -ENODEV
: data
[2];
324 static int lme2510_msg(struct dvb_usb_device
*d
,
325 u8
*wbuf
, int wlen
, u8
*rbuf
, int rlen
)
328 struct lme2510_state
*st
= d
->priv
;
330 if (mutex_lock_interruptible(&d
->i2c_mutex
) < 0)
333 if (st
->i2c_talk_onoff
== 1) {
335 ret
= lme2510_usb_talk(d
, wbuf
, wlen
, rbuf
, rlen
);
337 switch (st
->tuner_config
) {
339 if (wbuf
[2] == 0x1c) {
340 if (wbuf
[3] == 0x0e) {
341 st
->signal_lock
= rbuf
[1];
342 if ((st
->stream_on
& 1) &&
343 (st
->signal_lock
& 0x10)) {
344 lme2510_usb_talk_restart(d
,
345 wbuf
, wlen
, rbuf
, rlen
);
346 st
->i2c_talk_onoff
= 0;
353 if (wbuf
[2] == 0xd0) {
354 if (wbuf
[3] == 0x24) {
355 st
->signal_lock
= rbuf
[1];
356 if ((st
->stream_on
& 1) &&
357 (st
->signal_lock
& 0x8)) {
358 lme2510_usb_talk_restart(d
,
359 wbuf
, wlen
, rbuf
, rlen
);
360 st
->i2c_talk_onoff
= 0;
363 if ((wbuf
[3] != 0x6) & (wbuf
[3] != 0x5))
373 switch (st
->tuner_config
) {
378 rbuf
[1] = st
->signal_lock
;
382 rbuf
[1] = st
->signal_level
;
386 rbuf
[1] = st
->signal_sn
;
388 /*DiSEqC functions as per TDA10086*/
397 lme2510_usb_talk_restart(d
,
398 wbuf
, wlen
, rbuf
, rlen
);
407 rbuf
[1] = (st
->signal_level
& 0x80)
408 ? 0 : (st
->signal_level
* 2);
412 rbuf
[1] = st
->signal_sn
;
416 rbuf
[1] = (st
->signal_level
& 0x80)
417 ? 0 : st
->signal_lock
;
422 wbuf
, wlen
, rbuf
, rlen
);
425 if (st
->one_tune
> 0)
428 st
->i2c_talk_onoff
= 1;
429 /*DiSEqC functions as per STV0288*/
437 lme2510_usb_talk_restart(d
,
438 wbuf
, wlen
, rbuf
, rlen
);
451 deb_info(4, "I2C From Interupt Message out(%02x) in(%02x)",
456 mutex_unlock(&d
->i2c_mutex
);
462 static int lme2510_i2c_xfer(struct i2c_adapter
*adap
, struct i2c_msg msg
[],
465 struct dvb_usb_device
*d
= i2c_get_adapdata(adap
);
466 struct lme2510_state
*st
= d
->priv
;
467 static u8 obuf
[64], ibuf
[512];
470 u8 gate
= st
->i2c_gate
;
476 warn("more than 2 i2c messages"
477 "at a time is not handled yet. TODO.");
479 for (i
= 0; i
< num
; i
++) {
480 read_o
= 1 & (msg
[i
].flags
& I2C_M_RD
);
481 read
= i
+1 < num
&& (msg
[i
+1].flags
& I2C_M_RD
);
483 gate
= (msg
[i
].addr
== st
->i2c_tuner_addr
)
484 ? (read
) ? st
->i2c_tuner_gate_r
485 : st
->i2c_tuner_gate_w
487 obuf
[0] = gate
| (read
<< 7);
490 obuf
[1] = (read
) ? 2 : msg
[i
].len
+ 1;
492 obuf
[1] = msg
[i
].len
+ read
+ 1;
494 obuf
[2] = msg
[i
].addr
;
499 memcpy(&obuf
[3], msg
[i
].buf
, msg
[i
].len
);
500 obuf
[msg
[i
].len
+3] = msg
[i
+1].len
;
504 memcpy(&obuf
[3], msg
[i
].buf
, msg
[i
].len
);
508 if (lme2510_msg(d
, obuf
, len
, ibuf
, 512) < 0) {
509 deb_info(1, "i2c transfer failed.");
515 memcpy(msg
[i
].buf
, &ibuf
[1], msg
[i
].len
);
517 memcpy(msg
[i
+1].buf
, &ibuf
[1], msg
[i
+1].len
);
525 static u32
lme2510_i2c_func(struct i2c_adapter
*adapter
)
530 static struct i2c_algorithm lme2510_i2c_algo
= {
531 .master_xfer
= lme2510_i2c_xfer
,
532 .functionality
= lme2510_i2c_func
,
535 /* Callbacks for DVB USB */
536 static int lme2510_identify_state(struct usb_device
*udev
,
537 struct dvb_usb_device_properties
*props
,
538 struct dvb_usb_device_description
**desc
,
541 if (lme2510_return_status(udev
) == 0x44)
548 static int lme2510_streaming_ctrl(struct dvb_usb_adapter
*adap
, int onoff
)
550 struct lme2510_state
*st
= adap
->dev
->priv
;
551 static u8 stream_on
[] = LME_ST_ON_W
;
552 static u8 clear_reg_3
[] = LME_CLEAR_PID
;
555 int ret
= 0, len
= 2, rlen
= sizeof(rbuf
);
557 deb_info(1, "STM (%02x)", onoff
);
560 st
->i2c_talk_onoff
= 0;
562 /* wait for i2C to be free */
563 while (mutex_lock_interruptible(&adap
->dev
->i2c_mutex
) < 0) {
569 ret
|= lme2510_usb_talk(adap
->dev
,
570 stream_on
, len
, rbuf
, rlen
);
573 mutex_unlock(&adap
->dev
->i2c_mutex
);
575 deb_info(1, "STM Steam Off");
576 ret
|= lme2510_usb_talk(adap
->dev
, clear_reg_3
,
577 sizeof(clear_reg_3
), rbuf
, rlen
);
579 st
->i2c_talk_onoff
= 1;
582 return (ret
< 0) ? -ENODEV
: 0;
585 static int lme2510_int_service(struct dvb_usb_adapter
*adap
)
587 struct dvb_usb_device
*d
= adap
->dev
;
588 struct input_dev
*input_dev
;
589 char *ir_codes
= RC_MAP_LME2510
;
592 info("STA Configuring Remote");
594 usb_make_path(d
->udev
, d
->rc_phys
, sizeof(d
->rc_phys
));
596 strlcat(d
->rc_phys
, "/ir0", sizeof(d
->rc_phys
));
598 input_dev
= input_allocate_device();
602 input_dev
->name
= "LME2510 Remote Control";
603 input_dev
->phys
= d
->rc_phys
;
605 usb_to_input_id(d
->udev
, &input_dev
->id
);
607 ret
|= ir_input_register(input_dev
, ir_codes
, NULL
, "LME 2510");
610 input_free_device(input_dev
);
614 d
->rc_input_dev
= input_dev
;
615 /* Start the Interupt */
616 ret
= lme2510_int_read(adap
);
619 ir_input_unregister(input_dev
);
620 input_free_device(input_dev
);
622 return (ret
< 0) ? -ENODEV
: 0;
625 static u8
check_sum(u8
*p
, u8 len
)
633 static int lme2510_download_firmware(struct usb_device
*dev
,
634 const struct firmware
*fw
)
638 u16 j
, wlen
, len_in
, start
, end
;
639 u8 packet_size
, dlen
, i
;
646 info("FRM Starting Firmware Download");
648 for (i
= 1; i
< 3; i
++) {
649 start
= (i
== 1) ? 0 : 512;
650 end
= (i
== 1) ? 512 : fw
->size
;
651 for (j
= start
; j
< end
; j
+= (packet_size
+1)) {
652 fw_data
= (u8
*)(fw
->data
+ j
);
653 if ((end
- j
) > packet_size
) {
658 dlen
= (u8
)(end
- j
)-1;
661 memcpy(&data
[2], fw_data
, dlen
+1);
662 wlen
= (u8
) dlen
+ 4;
663 data
[wlen
-1] = check_sum(fw_data
, dlen
+1);
664 deb_info(1, "Data S=%02x:E=%02x CS= %02x", data
[3],
665 data
[dlen
+2], data
[dlen
+3]);
666 ret
|= lme2510_bulk_write(dev
, data
, wlen
, 1);
667 ret
|= lme2510_bulk_read(dev
, data
, len_in
, 1);
668 ret
|= (data
[0] == 0x88) ? 0 : -1;
671 usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
672 0x06, 0x80, 0x0200, 0x00, data
, 0x0109, 1000);
678 ret
|= lme2510_bulk_write(dev
, data
, len_in
, 1); /*Resetting*/
679 ret
|= lme2510_bulk_read(dev
, data
, len_in
, 1);
683 info("FRM Firmware Download Failed (%04x)" , ret
);
685 info("FRM Firmware Download Completed - Resetting Device");
688 return (ret
< 0) ? -ENODEV
: 0;
691 /* Default firmware for LME2510C */
692 const char lme_firmware
[50] = "dvb-usb-lme2510c-s7395.fw";
694 static void lme_coldreset(struct usb_device
*dev
)
701 info("FRM Firmware Cold Reset");
702 ret
|= lme2510_bulk_write(dev
, data
, len_in
, 1); /*Cold Resetting*/
703 ret
|= lme2510_bulk_read(dev
, data
, len_in
, 1);
707 static void lme_firmware_switch(struct usb_device
*udev
, int cold
)
709 const struct firmware
*fw
= NULL
;
710 char lme2510c_s7395
[] = "dvb-usb-lme2510c-s7395.fw";
711 char lme2510c_lg
[] = "dvb-usb-lme2510c-lg.fw";
712 char *firm_msg
[] = {"Loading", "Switching to"};
715 if (udev
->descriptor
.idProduct
== 0x1122)
718 switch (dvb_usb_lme2510_firmware
) {
721 memcpy(&lme_firmware
, lme2510c_s7395
, sizeof(lme2510c_s7395
));
722 ret
= request_firmware(&fw
, lme_firmware
, &udev
->dev
);
724 info("FRM %s S7395 Firmware", firm_msg
[cold
]);
728 dvb_usb_lme2510_firmware
= 1;
732 memcpy(&lme_firmware
, lme2510c_lg
, sizeof(lme2510c_lg
));
733 ret
= request_firmware(&fw
, lme_firmware
, &udev
->dev
);
735 info("FRM %s LG Firmware", firm_msg
[cold
]);
738 info("FRM No Firmware Found - please install");
739 dvb_usb_lme2510_firmware
= 0;
743 release_firmware(fw
);
749 static int lme2510_kill_urb(struct usb_data_stream
*stream
)
752 for (i
= 0; i
< stream
->urbs_submitted
; i
++) {
753 deb_info(3, "killing URB no. %d.", i
);
756 usb_kill_urb(stream
->urb_list
[i
]);
758 stream
->urbs_submitted
= 0;
762 static struct tda10086_config tda10086_config
= {
763 .demod_address
= 0x1c,
766 .xtal_freq
= TDA10086_XTAL_16M
,
769 static struct stv0288_config lme_config
= {
770 .demod_address
= 0xd0,
772 .inittab
= s7395_inittab
,
775 static struct ix2505v_config lme_tuner
= {
776 .tuner_address
= 0xc0,
779 .tuner_chargepump
= 0x3,
782 static int dm04_lme2510_set_voltage(struct dvb_frontend
*fe
,
783 fe_sec_voltage_t voltage
)
785 struct dvb_usb_adapter
*adap
= fe
->dvb
->priv
;
786 struct lme2510_state
*st
= adap
->dev
->priv
;
787 static u8 voltage_low
[] = LME_VOLTAGE_L
;
788 static u8 voltage_high
[] = LME_VOLTAGE_H
;
789 static u8 lnb_on
[] = LNB_ON
;
790 static u8 lnb_off
[] = LNB_OFF
;
792 int ret
= 0, len
= 3, rlen
= 1;
794 if (st
->stream_on
== 1)
797 ret
|= lme2510_usb_talk(adap
->dev
, lnb_on
, len
, rbuf
, rlen
);
801 ret
|= lme2510_usb_talk(adap
->dev
,
802 voltage_high
, len
, rbuf
, rlen
);
805 case SEC_VOLTAGE_OFF
:
806 ret
|= lme2510_usb_talk(adap
->dev
,
807 lnb_off
, len
, rbuf
, rlen
);
810 ret
|= lme2510_usb_talk(adap
->dev
,
811 voltage_low
, len
, rbuf
, rlen
);
816 st
->i2c_talk_onoff
= 1;
817 return (ret
< 0) ? -ENODEV
: 0;
820 static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter
*adap
)
823 struct lme2510_state
*st
= adap
->dev
->priv
;
826 ret
= lme2510_int_service(adap
);
828 info("INT Unable to start Interupt Service");
832 st
->i2c_talk_onoff
= 1;
835 adap
->fe
= dvb_attach(tda10086_attach
, &tda10086_config
,
836 &adap
->dev
->i2c_adap
);
839 info("TUN Found Frontend TDA10086");
840 memcpy(&adap
->fe
->ops
.info
.name
,
841 &"DM04_LG_TDQY-P001F DVB-S", 24);
842 adap
->fe
->ops
.set_voltage
= dm04_lme2510_set_voltage
;
843 st
->i2c_tuner_gate_w
= 4;
844 st
->i2c_tuner_gate_r
= 4;
845 st
->i2c_tuner_addr
= 0xc0;
846 if (dvb_attach(tda826x_attach
, adap
->fe
, 0xc0,
847 &adap
->dev
->i2c_adap
, 1)) {
848 info("TUN TDA8263 Found");
849 st
->tuner_config
= TUNER_LG
;
850 if (dvb_usb_lme2510_firmware
!= 1) {
851 dvb_usb_lme2510_firmware
= 1;
852 lme_firmware_switch(adap
->dev
->udev
, 1);
860 adap
->fe
= dvb_attach(stv0288_attach
, &lme_config
,
861 &adap
->dev
->i2c_adap
);
864 info("FE Found Stv0288");
865 memcpy(&adap
->fe
->ops
.info
.name
,
866 &"DM04_SHARP:BS2F7HZ7395", 22);
867 adap
->fe
->ops
.set_voltage
= dm04_lme2510_set_voltage
;
868 st
->i2c_tuner_gate_w
= 4;
869 st
->i2c_tuner_gate_r
= 5;
870 st
->i2c_tuner_addr
= 0xc0;
871 if (dvb_attach(ix2505v_attach
, adap
->fe
, &lme_tuner
,
872 &adap
->dev
->i2c_adap
)) {
873 st
->tuner_config
= TUNER_S7395
;
874 info("TUN Sharp IX2505V silicon tuner");
875 if (dvb_usb_lme2510_firmware
!= 0) {
876 dvb_usb_lme2510_firmware
= 0;
877 lme_firmware_switch(adap
->dev
->udev
, 1);
885 info("DM04 Not Supported");
889 static int lme2510_powerup(struct dvb_usb_device
*d
, int onoff
)
891 struct lme2510_state
*st
= d
->priv
;
892 st
->i2c_talk_onoff
= 1;
896 /* DVB USB Driver stuff */
897 static struct dvb_usb_device_properties lme2510_properties
;
898 static struct dvb_usb_device_properties lme2510c_properties
;
900 static int lme2510_probe(struct usb_interface
*intf
,
901 const struct usb_device_id
*id
)
903 struct usb_device
*udev
= interface_to_usbdev(intf
);
906 usb_reset_configuration(udev
);
908 usb_set_interface(udev
, intf
->cur_altsetting
->desc
.bInterfaceNumber
, 1);
910 if (udev
->speed
!= USB_SPEED_HIGH
) {
911 ret
= usb_reset_device(udev
);
912 info("DEV Failed to connect in HIGH SPEED mode");
916 lme_firmware_switch(udev
, 0);
918 if (0 == dvb_usb_device_init(intf
, &lme2510_properties
,
919 THIS_MODULE
, NULL
, adapter_nr
)) {
920 info("DEV registering device driver");
923 if (0 == dvb_usb_device_init(intf
, &lme2510c_properties
,
924 THIS_MODULE
, NULL
, adapter_nr
)) {
925 info("DEV registering device driver");
929 info("DEV lme2510 Error");
934 static struct usb_device_id lme2510_table
[] = {
935 { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
936 { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
937 {} /* Terminating entry */
940 MODULE_DEVICE_TABLE(usb
, lme2510_table
);
942 static struct dvb_usb_device_properties lme2510_properties
= {
943 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
944 .usb_ctrl
= DEVICE_SPECIFIC
,
945 .download_firmware
= lme2510_download_firmware
,
946 .firmware
= "dvb-usb-lme2510-lg.fw",
948 .size_of_priv
= sizeof(struct lme2510_state
),
952 .streaming_ctrl
= lme2510_streaming_ctrl
,
953 .frontend_attach
= dm04_lme2510_frontend_attach
,
954 /* parameter for the MPEG2-data transfer */
968 .power_ctrl
= lme2510_powerup
,
969 .identify_state
= lme2510_identify_state
,
970 .i2c_algo
= &lme2510_i2c_algo
,
971 .generic_bulk_ctrl_endpoint
= 0,
972 .num_device_descs
= 1,
974 { "DM04 LME2510 DVB-S USB 2.0",
975 { &lme2510_table
[0], NULL
},
981 static struct dvb_usb_device_properties lme2510c_properties
= {
982 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
983 .usb_ctrl
= DEVICE_SPECIFIC
,
984 .download_firmware
= lme2510_download_firmware
,
985 .firmware
= lme_firmware
,
986 .size_of_priv
= sizeof(struct lme2510_state
),
990 .streaming_ctrl
= lme2510_streaming_ctrl
,
991 .frontend_attach
= dm04_lme2510_frontend_attach
,
992 /* parameter for the MPEG2-data transfer */
1006 .power_ctrl
= lme2510_powerup
,
1007 .identify_state
= lme2510_identify_state
,
1008 .i2c_algo
= &lme2510_i2c_algo
,
1009 .generic_bulk_ctrl_endpoint
= 0,
1010 .num_device_descs
= 1,
1012 { "DM04 LME2510C USB2.0",
1013 { &lme2510_table
[1], NULL
},
1018 void *lme2510_exit_int(struct dvb_usb_device
*d
)
1020 struct lme2510_state
*st
= d
->priv
;
1021 struct dvb_usb_adapter
*adap
= &d
->adapter
[0];
1022 void *buffer
= NULL
;
1025 lme2510_kill_urb(&adap
->stream
);
1026 adap
->feedcount
= 0;
1029 if (st
->lme_urb
!= NULL
) {
1030 st
->i2c_talk_onoff
= 1;
1031 st
->signal_lock
= 0;
1032 st
->signal_level
= 0;
1034 buffer
= st
->usb_buffer
;
1035 usb_kill_urb(st
->lme_urb
);
1036 usb_free_coherent(d
->udev
, 5000, st
->buffer
,
1037 st
->lme_urb
->transfer_dma
);
1038 info("Interupt Service Stopped");
1039 ir_input_unregister(d
->rc_input_dev
);
1040 info("Remote Stopped");
1045 void lme2510_exit(struct usb_interface
*intf
)
1047 struct dvb_usb_device
*d
= usb_get_intfdata(intf
);
1051 usb_buffer
= lme2510_exit_int(d
);
1052 dvb_usb_device_exit(intf
);
1057 static struct usb_driver lme2510_driver
= {
1058 .name
= "LME2510C_DVBS",
1059 .probe
= lme2510_probe
,
1060 .disconnect
= lme2510_exit
,
1061 .id_table
= lme2510_table
,
1065 static int __init
lme2510_module_init(void)
1067 int result
= usb_register(&lme2510_driver
);
1069 err("usb_register failed. Error number %d", result
);
1076 static void __exit
lme2510_module_exit(void)
1078 /* deregister this driver from the USB subsystem */
1079 usb_deregister(&lme2510_driver
);
1082 module_init(lme2510_module_init
);
1083 module_exit(lme2510_module_exit
);
1085 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1086 MODULE_DESCRIPTION("LM2510(C) DVB-S USB2.0");
1087 MODULE_VERSION("1.60");
1088 MODULE_LICENSE("GPL");