2 * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
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.
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.
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.
27 static int dvb_usb_ce6230_debug
;
28 module_param_named(debug
, dvb_usb_ce6230_debug
, int, 0644);
29 MODULE_PARM_DESC(debug
, "set debugging level" DVB_USB_DEBUG_STATUS
);
30 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
32 static struct zl10353_config ce6230_zl10353_config
;
34 static int ce6230_rw_udev(struct usb_device
*udev
, struct req_t
*req
)
42 u8 buf
[req
->data_len
];
52 requesttype
= (USB_TYPE_VENDOR
| USB_DIR_IN
);
57 requesttype
= (USB_TYPE_VENDOR
| USB_DIR_OUT
);
60 err("unknown command:%02x", req
->cmd
);
65 if (requesttype
== (USB_TYPE_VENDOR
| USB_DIR_OUT
)) {
67 memcpy(buf
, req
->data
, req
->data_len
);
68 pipe
= usb_sndctrlpipe(udev
, 0);
71 pipe
= usb_rcvctrlpipe(udev
, 0);
74 msleep(1); /* avoid I2C errors */
76 ret
= usb_control_msg(udev
, pipe
, request
, requesttype
, value
, index
,
77 buf
, sizeof(buf
), CE6230_USB_TIMEOUT
);
79 ce6230_debug_dump(request
, requesttype
, value
, index
, buf
,
80 req
->data_len
, deb_xfer
);
83 deb_info("%s: usb_control_msg failed:%d\n", __func__
, ret
);
87 /* read request, copy returned data to return buf */
88 if (!ret
&& requesttype
== (USB_TYPE_VENDOR
| USB_DIR_IN
))
89 memcpy(req
->data
, buf
, req
->data_len
);
95 static int ce6230_ctrl_msg(struct dvb_usb_device
*d
, struct req_t
*req
)
97 return ce6230_rw_udev(d
->udev
, req
);
101 static int ce6230_i2c_xfer(struct i2c_adapter
*adap
, struct i2c_msg msg
[],
104 struct dvb_usb_device
*d
= i2c_get_adapdata(adap
);
108 memset(&req
, 0, sizeof(req
));
113 if (mutex_lock_interruptible(&d
->i2c_mutex
) < 0)
117 if (num
> i
+ 1 && (msg
[i
+1].flags
& I2C_M_RD
)) {
119 ce6230_zl10353_config
.demod_address
) {
120 req
.cmd
= DEMOD_READ
;
121 req
.value
= msg
[i
].addr
>> 1;
122 req
.index
= msg
[i
].buf
[0];
123 req
.data_len
= msg
[i
+1].len
;
124 req
.data
= &msg
[i
+1].buf
[0];
125 ret
= ce6230_ctrl_msg(d
, &req
);
127 err("i2c read not implemented");
133 ce6230_zl10353_config
.demod_address
) {
134 req
.cmd
= DEMOD_WRITE
;
135 req
.value
= msg
[i
].addr
>> 1;
136 req
.index
= msg
[i
].buf
[0];
137 req
.data_len
= msg
[i
].len
-1;
138 req
.data
= &msg
[i
].buf
[1];
139 ret
= ce6230_ctrl_msg(d
, &req
);
142 req
.value
= 0x2000 + (msg
[i
].addr
>> 1);
144 req
.data_len
= msg
[i
].len
;
145 req
.data
= &msg
[i
].buf
[0];
146 ret
= ce6230_ctrl_msg(d
, &req
);
154 mutex_unlock(&d
->i2c_mutex
);
155 return ret
? ret
: i
;
158 static u32
ce6230_i2c_func(struct i2c_adapter
*adapter
)
163 static struct i2c_algorithm ce6230_i2c_algo
= {
164 .master_xfer
= ce6230_i2c_xfer
,
165 .functionality
= ce6230_i2c_func
,
168 /* Callbacks for DVB USB */
169 static struct zl10353_config ce6230_zl10353_config
= {
170 .demod_address
= 0x1e,
179 static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter
*adap
)
181 deb_info("%s:\n", __func__
);
182 adap
->fe
= dvb_attach(zl10353_attach
, &ce6230_zl10353_config
,
183 &adap
->dev
->i2c_adap
);
184 if (adap
->fe
== NULL
)
189 static struct mxl5005s_config ce6230_mxl5003s_config
= {
191 .if_freq
= IF_FREQ_4570000HZ
,
192 .xtal_freq
= CRYSTAL_FREQ_16000000HZ
,
193 .agc_mode
= MXL_SINGLE_AGC
,
194 .tracking_filter
= MXL_TF_DEFAULT
,
195 .rssi_enable
= MXL_RSSI_ENABLE
,
196 .cap_select
= MXL_CAP_SEL_ENABLE
,
197 .div_out
= MXL_DIV_OUT_4
,
198 .clock_out
= MXL_CLOCK_OUT_DISABLE
,
199 .output_load
= MXL5005S_IF_OUTPUT_LOAD_200_OHM
,
200 .top
= MXL5005S_TOP_25P2
,
201 .mod_mode
= MXL_DIGITAL_MODE
,
202 .if_mode
= MXL_ZERO_IF
,
203 .AgcMasterByte
= 0x00,
206 static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter
*adap
)
209 deb_info("%s:\n", __func__
);
210 ret
= dvb_attach(mxl5005s_attach
, adap
->fe
, &adap
->dev
->i2c_adap
,
211 &ce6230_mxl5003s_config
) == NULL
? -ENODEV
: 0;
215 static int ce6230_power_ctrl(struct dvb_usb_device
*d
, int onoff
)
218 deb_info("%s: onoff:%d\n", __func__
, onoff
);
220 /* InterfaceNumber 1 / AlternateSetting 0 idle
221 InterfaceNumber 1 / AlternateSetting 1 streaming */
222 ret
= usb_set_interface(d
->udev
, 1, onoff
);
224 err("usb_set_interface failed with error:%d", ret
);
229 /* DVB USB Driver stuff */
230 static struct dvb_usb_device_properties ce6230_properties
;
232 static int ce6230_probe(struct usb_interface
*intf
,
233 const struct usb_device_id
*id
)
236 struct dvb_usb_device
*d
= NULL
;
238 deb_info("%s: interface:%d\n", __func__
,
239 intf
->cur_altsetting
->desc
.bInterfaceNumber
);
241 if (intf
->cur_altsetting
->desc
.bInterfaceNumber
== 1) {
242 ret
= dvb_usb_device_init(intf
, &ce6230_properties
, THIS_MODULE
,
245 err("init failed with error:%d\n", ret
);
251 static struct usb_device_id ce6230_table
[] = {
252 { USB_DEVICE(USB_VID_INTEL
, USB_PID_INTEL_CE9500
) },
253 { USB_DEVICE(USB_VID_AVERMEDIA
, USB_PID_AVERMEDIA_A310
) },
254 { } /* Terminating entry */
256 MODULE_DEVICE_TABLE(usb
, ce6230_table
);
258 static struct dvb_usb_device_properties ce6230_properties
= {
259 .caps
= DVB_USB_IS_AN_I2C_ADAPTER
,
261 .usb_ctrl
= DEVICE_SPECIFIC
,
269 .frontend_attach
= ce6230_zl10353_frontend_attach
,
270 .tuner_attach
= ce6230_mxl5003s_tuner_attach
,
277 .buffersize
= (16*512),
284 .power_ctrl
= ce6230_power_ctrl
,
286 .i2c_algo
= &ce6230_i2c_algo
,
288 .num_device_descs
= 2,
291 .name
= "Intel CE9500 reference design",
293 .warm_ids
= {&ce6230_table
[0], NULL
},
296 .name
= "AVerMedia A310 USB 2.0 DVB-T tuner",
298 .warm_ids
= {&ce6230_table
[1], NULL
},
303 static struct usb_driver ce6230_driver
= {
304 .name
= "dvb_usb_ce6230",
305 .probe
= ce6230_probe
,
306 .disconnect
= dvb_usb_device_exit
,
307 .id_table
= ce6230_table
,
311 static int __init
ce6230_module_init(void)
314 deb_info("%s:\n", __func__
);
315 ret
= usb_register(&ce6230_driver
);
317 err("usb_register failed with error:%d", ret
);
322 static void __exit
ce6230_module_exit(void)
324 deb_info("%s:\n", __func__
);
325 /* deregister this driver from the USB subsystem */
326 usb_deregister(&ce6230_driver
);
329 module_init(ce6230_module_init
);
330 module_exit(ce6230_module_exit
);
332 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
333 MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
334 MODULE_LICENSE("GPL");