22 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
33 * TeVii S600, S630, S650, S660, S480, S421, S632
44 * Prof 1100, 7500,
5- * Geniatech SU3000, T220 Cards
5+ * Geniatech SU3000, T220,
6+ * TechnoTrend S2-4600 Cards
67 * Copyright (C) 2008-2012 Igor M. Liplianin (liplianin@me.by)
78 *
89 * This program is free software; you can redistribute it and/or modify it
3132#include "m88rs2000.h"
3233#include "tda18271.h"
3334#include "cxd2820r.h"
35+ #include "m88ds3103.h"
36+ #include "m88ts2022.h"
3437
3538/* Max transfer size done by I2C transfer functions */
3639#define MAX_XFER_SIZE 64
@@ -1115,6 +1118,22 @@ static struct tda18271_config tda18271_config = {
11151118 .gate = TDA18271_GATE_DIGITAL ,
11161119};
11171120
1121+ static const struct m88ds3103_config tt_s2_4600_m88ds3103_config = {
1122+ .i2c_addr = 0x68 ,
1123+ .clock = 27000000 ,
1124+ .i2c_wr_max = 33 ,
1125+ .ts_mode = M88DS3103_TS_CI ,
1126+ .ts_clk = 16000 ,
1127+ .ts_clk_pol = 0 ,
1128+ .spec_inv = 0 ,
1129+ .agc_inv = 0 ,
1130+ .clock_out = M88DS3103_CLOCK_OUT_ENABLED ,
1131+ .envelope_mode = 0 ,
1132+ .agc = 0x99 ,
1133+ .lnb_hv_pol = 1 ,
1134+ .lnb_en_pol = 0 ,
1135+ };
1136+
11181137static u8 m88rs2000_inittab [] = {
11191138 DEMOD_WRITE , 0x9a , 0x30 ,
11201139 DEMOD_WRITE , 0x00 , 0x01 ,
@@ -1459,6 +1478,86 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
14591478 return - EIO ;
14601479}
14611480
1481+ static int tt_s2_4600_frontend_attach (struct dvb_usb_adapter * adap )
1482+ {
1483+ struct dvb_usb_device * d = adap -> dev ;
1484+ struct dw2102_state * state = d -> priv ;
1485+ u8 obuf [3 ] = { 0xe , 0x80 , 0 };
1486+ u8 ibuf [] = { 0 };
1487+ struct i2c_adapter * i2c_adapter ;
1488+ struct i2c_client * client ;
1489+ struct i2c_board_info info ;
1490+ struct m88ts2022_config m88ts2022_config = {
1491+ .clock = 27000000 ,
1492+ };
1493+
1494+ if (dvb_usb_generic_rw (d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
1495+ err ("command 0x0e transfer failed." );
1496+
1497+ obuf [0 ] = 0xe ;
1498+ obuf [1 ] = 0x02 ;
1499+ obuf [2 ] = 1 ;
1500+
1501+ if (dvb_usb_generic_rw (d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
1502+ err ("command 0x0e transfer failed." );
1503+ msleep (300 );
1504+
1505+ obuf [0 ] = 0xe ;
1506+ obuf [1 ] = 0x83 ;
1507+ obuf [2 ] = 0 ;
1508+
1509+ if (dvb_usb_generic_rw (d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
1510+ err ("command 0x0e transfer failed." );
1511+
1512+ obuf [0 ] = 0xe ;
1513+ obuf [1 ] = 0x83 ;
1514+ obuf [2 ] = 1 ;
1515+
1516+ if (dvb_usb_generic_rw (d , obuf , 3 , ibuf , 1 , 0 ) < 0 )
1517+ err ("command 0x0e transfer failed." );
1518+
1519+ obuf [0 ] = 0x51 ;
1520+
1521+ if (dvb_usb_generic_rw (d , obuf , 1 , ibuf , 1 , 0 ) < 0 )
1522+ err ("command 0x51 transfer failed." );
1523+
1524+ memset (& info , 0 , sizeof (struct i2c_board_info ));
1525+
1526+ adap -> fe_adap [0 ].fe = dvb_attach (m88ds3103_attach ,
1527+ & tt_s2_4600_m88ds3103_config ,
1528+ & d -> i2c_adap ,
1529+ & i2c_adapter );
1530+ if (adap -> fe_adap [0 ].fe == NULL )
1531+ return - ENODEV ;
1532+
1533+ /* attach tuner */
1534+ m88ts2022_config .fe = adap -> fe_adap [0 ].fe ;
1535+ strlcpy (info .type , "m88ts2022" , I2C_NAME_SIZE );
1536+ info .addr = 0x60 ;
1537+ info .platform_data = & m88ts2022_config ;
1538+ request_module ("m88ts2022" );
1539+ client = i2c_new_device (i2c_adapter , & info );
1540+
1541+ if (client == NULL || client -> dev .driver == NULL ) {
1542+ dvb_frontend_detach (adap -> fe_adap [0 ].fe );
1543+ return - ENODEV ;
1544+ }
1545+
1546+ if (!try_module_get (client -> dev .driver -> owner )) {
1547+ i2c_unregister_device (client );
1548+ dvb_frontend_detach (adap -> fe_adap [0 ].fe );
1549+ return - ENODEV ;
1550+ }
1551+
1552+ /* delegate signal strength measurement to tuner */
1553+ adap -> fe_adap [0 ].fe -> ops .read_signal_strength =
1554+ adap -> fe_adap [0 ].fe -> ops .tuner_ops .get_rf_strength ;
1555+
1556+ state -> i2c_client_tuner = client ;
1557+
1558+ return 0 ;
1559+ }
1560+
14621561static int dw2102_tuner_attach (struct dvb_usb_adapter * adap )
14631562{
14641563 dvb_attach (dvb_pll_attach , adap -> fe_adap [0 ].fe , 0x60 ,
@@ -1559,6 +1658,7 @@ enum dw2102_table_entry {
15591658 TERRATEC_CINERGY_S2_R2 ,
15601659 GOTVIEW_SAT_HD ,
15611660 GENIATECH_T220 ,
1661+ TECHNOTREND_S2_4600 ,
15621662};
15631663
15641664static struct usb_device_id dw2102_table [] = {
@@ -1582,6 +1682,8 @@ static struct usb_device_id dw2102_table[] = {
15821682 [TERRATEC_CINERGY_S2_R2 ] = {USB_DEVICE (USB_VID_TERRATEC , 0x00b0 )},
15831683 [GOTVIEW_SAT_HD ] = {USB_DEVICE (0x1FE1 , USB_PID_GOTVIEW_SAT_HD )},
15841684 [GENIATECH_T220 ] = {USB_DEVICE (0x1f4d , 0xD220 )},
1685+ [TECHNOTREND_S2_4600 ] = {USB_DEVICE (USB_VID_TECHNOTREND ,
1686+ USB_PID_TECHNOTREND_CONNECT_S2_4600 )},
15851687 { }
15861688};
15871689
@@ -2059,6 +2161,55 @@ static struct dvb_usb_device_properties t220_properties = {
20592161 }
20602162};
20612163
2164+ static struct dvb_usb_device_properties tt_s2_4600_properties = {
2165+ .caps = DVB_USB_IS_AN_I2C_ADAPTER ,
2166+ .usb_ctrl = DEVICE_SPECIFIC ,
2167+ .size_of_priv = sizeof (struct dw2102_state ),
2168+ .power_ctrl = su3000_power_ctrl ,
2169+ .num_adapters = 1 ,
2170+ .identify_state = su3000_identify_state ,
2171+ .i2c_algo = & su3000_i2c_algo ,
2172+
2173+ .rc .core = {
2174+ .rc_interval = 250 ,
2175+ .rc_codes = RC_MAP_TT_1500 ,
2176+ .module_name = "dw2102" ,
2177+ .allowed_protos = RC_BIT_RC5 ,
2178+ .rc_query = su3000_rc_query ,
2179+ },
2180+
2181+ .read_mac_address = su3000_read_mac_address ,
2182+
2183+ .generic_bulk_ctrl_endpoint = 0x01 ,
2184+
2185+ .adapter = {
2186+ {
2187+ .num_frontends = 1 ,
2188+ .fe = {{
2189+ .streaming_ctrl = su3000_streaming_ctrl ,
2190+ .frontend_attach = tt_s2_4600_frontend_attach ,
2191+ .stream = {
2192+ .type = USB_BULK ,
2193+ .count = 8 ,
2194+ .endpoint = 0x82 ,
2195+ .u = {
2196+ .bulk = {
2197+ .buffersize = 4096 ,
2198+ }
2199+ }
2200+ }
2201+ } },
2202+ }
2203+ },
2204+ .num_device_descs = 1 ,
2205+ .devices = {
2206+ { "TechnoTrend TT-connect S2-4600" ,
2207+ { & dw2102_table [TECHNOTREND_S2_4600 ], NULL },
2208+ { NULL },
2209+ },
2210+ }
2211+ };
2212+
20622213static int dw2102_probe (struct usb_interface * intf ,
20632214 const struct usb_device_id * id )
20642215{
@@ -2133,6 +2284,8 @@ static int dw2102_probe(struct usb_interface *intf,
21332284 0 == dvb_usb_device_init (intf , & su3000_properties ,
21342285 THIS_MODULE , NULL , adapter_nr ) ||
21352286 0 == dvb_usb_device_init (intf , & t220_properties ,
2287+ THIS_MODULE , NULL , adapter_nr ) ||
2288+ 0 == dvb_usb_device_init (intf , & tt_s2_4600_properties ,
21362289 THIS_MODULE , NULL , adapter_nr ))
21372290 return 0 ;
21382291
@@ -2169,7 +2322,8 @@ MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
21692322 " DVB-C 3101 USB2.0,"
21702323 " TeVii S600, S630, S650, S660, S480, S421, S632"
21712324 " Prof 1100, 7500 USB2.0,"
2172- " Geniatech SU3000, T220 devices" );
2325+ " Geniatech SU3000, T220,"
2326+ " TechnoTrend S2-4600 devices" );
21732327MODULE_VERSION ("0.1" );
21742328MODULE_LICENSE ("GPL" );
21752329MODULE_FIRMWARE (DW2101_FIRMWARE );
0 commit comments