2 * Intel CE6230 DVB USB driver
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.
24 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
26 static int ce6230_ctrl_msg(struct dvb_usb_device
*d
, struct usb_req
*req
)
44 requesttype
= (USB_TYPE_VENDOR
| USB_DIR_IN
);
49 requesttype
= (USB_TYPE_VENDOR
| USB_DIR_OUT
);
52 dev_err(&d
->udev
->dev
, "%s: unknown command=%02x\n",
53 KBUILD_MODNAME
, req
->cmd
);
58 buf
= kmalloc(req
->data_len
, GFP_KERNEL
);
64 if (requesttype
== (USB_TYPE_VENDOR
| USB_DIR_OUT
)) {
66 memcpy(buf
, req
->data
, req
->data_len
);
67 pipe
= usb_sndctrlpipe(d
->udev
, 0);
70 pipe
= usb_rcvctrlpipe(d
->udev
, 0);
73 msleep(1); /* avoid I2C errors */
75 ret
= usb_control_msg(d
->udev
, pipe
, request
, requesttype
, value
, index
,
76 buf
, req
->data_len
, CE6230_USB_TIMEOUT
);
78 dvb_usb_dbg_usb_control_msg(d
->udev
, request
, requesttype
, value
, index
,
82 dev_err(&d
->udev
->dev
, "%s: usb_control_msg() failed=%d\n",
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
);
97 static struct zl10353_config ce6230_zl10353_config
;
99 static int ce6230_i2c_master_xfer(struct i2c_adapter
*adap
,
100 struct i2c_msg msg
[], int num
)
102 struct dvb_usb_device
*d
= i2c_get_adapdata(adap
);
109 memset(&req
, 0, sizeof(req
));
111 if (mutex_lock_interruptible(&d
->i2c_mutex
) < 0)
115 if (num
> i
+ 1 && (msg
[i
+1].flags
& I2C_M_RD
)) {
117 ce6230_zl10353_config
.demod_address
) {
118 req
.cmd
= DEMOD_READ
;
119 req
.value
= msg
[i
].addr
>> 1;
120 req
.index
= msg
[i
].buf
[0];
121 req
.data_len
= msg
[i
+1].len
;
122 req
.data
= &msg
[i
+1].buf
[0];
123 ret
= ce6230_ctrl_msg(d
, &req
);
125 dev_err(&d
->udev
->dev
, "%s: I2C read not " \
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_functionality(struct i2c_adapter
*adapter
)
163 static struct i2c_algorithm ce6230_i2c_algorithm
= {
164 .master_xfer
= ce6230_i2c_master_xfer
,
165 .functionality
= ce6230_i2c_functionality
,
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 struct dvb_usb_device
*d
= adap_to_d(adap
);
183 dev_dbg(&d
->udev
->dev
, "%s:\n", __func__
);
185 adap
->fe
[0] = dvb_attach(zl10353_attach
, &ce6230_zl10353_config
,
187 if (adap
->fe
[0] == NULL
)
193 static struct mxl5005s_config ce6230_mxl5003s_config
= {
195 .if_freq
= IF_FREQ_4570000HZ
,
196 .xtal_freq
= CRYSTAL_FREQ_16000000HZ
,
197 .agc_mode
= MXL_SINGLE_AGC
,
198 .tracking_filter
= MXL_TF_DEFAULT
,
199 .rssi_enable
= MXL_RSSI_ENABLE
,
200 .cap_select
= MXL_CAP_SEL_ENABLE
,
201 .div_out
= MXL_DIV_OUT_4
,
202 .clock_out
= MXL_CLOCK_OUT_DISABLE
,
203 .output_load
= MXL5005S_IF_OUTPUT_LOAD_200_OHM
,
204 .top
= MXL5005S_TOP_25P2
,
205 .mod_mode
= MXL_DIGITAL_MODE
,
206 .if_mode
= MXL_ZERO_IF
,
207 .AgcMasterByte
= 0x00,
210 static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter
*adap
)
212 struct dvb_usb_device
*d
= adap_to_d(adap
);
215 dev_dbg(&d
->udev
->dev
, "%s:\n", __func__
);
217 ret
= dvb_attach(mxl5005s_attach
, adap
->fe
[0], &d
->i2c_adap
,
218 &ce6230_mxl5003s_config
) == NULL
? -ENODEV
: 0;
222 static int ce6230_power_ctrl(struct dvb_usb_device
*d
, int onoff
)
226 dev_dbg(&d
->udev
->dev
, "%s: onoff=%d\n", __func__
, onoff
);
228 /* InterfaceNumber 1 / AlternateSetting 0 idle
229 InterfaceNumber 1 / AlternateSetting 1 streaming */
230 ret
= usb_set_interface(d
->udev
, 1, onoff
);
232 dev_err(&d
->udev
->dev
, "%s: usb_set_interface() failed=%d\n",
233 KBUILD_MODNAME
, ret
);
238 /* DVB USB Driver stuff */
239 static struct dvb_usb_device_properties ce6230_props
= {
240 .driver_name
= KBUILD_MODNAME
,
241 .owner
= THIS_MODULE
,
242 .adapter_nr
= adapter_nr
,
243 .bInterfaceNumber
= 1,
245 .i2c_algo
= &ce6230_i2c_algorithm
,
246 .power_ctrl
= ce6230_power_ctrl
,
247 .frontend_attach
= ce6230_zl10353_frontend_attach
,
248 .tuner_attach
= ce6230_mxl5003s_tuner_attach
,
259 .buffersize
= (16 * 512),
267 static const struct usb_device_id ce6230_id_table
[] = {
268 { DVB_USB_DEVICE(USB_VID_INTEL
, USB_PID_INTEL_CE9500
,
269 &ce6230_props
, "Intel CE9500 reference design", NULL
) },
270 { DVB_USB_DEVICE(USB_VID_AVERMEDIA
, USB_PID_AVERMEDIA_A310
,
271 &ce6230_props
, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL
) },
274 MODULE_DEVICE_TABLE(usb
, ce6230_id_table
);
276 static struct usb_driver ce6230_usb_driver
= {
277 .name
= KBUILD_MODNAME
,
278 .id_table
= ce6230_id_table
,
279 .probe
= dvb_usbv2_probe
,
280 .disconnect
= dvb_usbv2_disconnect
,
281 .suspend
= dvb_usbv2_suspend
,
282 .resume
= dvb_usbv2_resume
,
283 .reset_resume
= dvb_usbv2_reset_resume
,
288 module_usb_driver(ce6230_usb_driver
);
290 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
291 MODULE_DESCRIPTION("Intel CE6230 driver");
292 MODULE_LICENSE("GPL");