Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dtv5100.c
Go to the documentation of this file.
1 /*
2  * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3  *
4  * Copyright (C) 2008 Antoine Jacquet <[email protected]>
5  * http://royale.zerezo.com/dtv5100/
6  *
7  * Inspired by gl861.c and au6610.c drivers
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include "dtv5100.h"
25 #include "zl10353.h"
26 #include "qt1010.h"
27 
28 /* debug */
29 static int dvb_usb_dtv5100_debug;
30 module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
31 MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
33 
34 static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
35  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
36 {
37  u8 request;
38  u8 type;
39  u16 value;
40  u16 index;
41 
42  switch (wlen) {
43  case 1:
44  /* write { reg }, read { value } */
45  request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
47  type = USB_TYPE_VENDOR | USB_DIR_IN;
48  value = 0;
49  break;
50  case 2:
51  /* write { reg, value } */
52  request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
55  value = wbuf[1];
56  break;
57  default:
58  warn("wlen = %x, aborting.", wlen);
59  return -EINVAL;
60  }
61  index = (addr << 8) + wbuf[0];
62 
63  msleep(1); /* avoid I2C errors */
64  return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
65  type, value, index, rbuf, rlen,
67 }
68 
69 /* I2C */
70 static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
71  int num)
72 {
73  struct dvb_usb_device *d = i2c_get_adapdata(adap);
74  int i;
75 
76  if (num > 2)
77  return -EINVAL;
78 
80  return -EAGAIN;
81 
82  for (i = 0; i < num; i++) {
83  /* write/read request */
84  if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
85  if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
86  msg[i].len, msg[i+1].buf,
87  msg[i+1].len) < 0)
88  break;
89  i++;
90  } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
91  msg[i].len, NULL, 0) < 0)
92  break;
93  }
94 
96  return i;
97 }
98 
99 static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
100 {
101  return I2C_FUNC_I2C;
102 }
103 
104 static struct i2c_algorithm dtv5100_i2c_algo = {
105  .master_xfer = dtv5100_i2c_xfer,
106  .functionality = dtv5100_i2c_func,
107 };
108 
109 /* Callbacks for DVB USB */
110 static struct zl10353_config dtv5100_zl10353_config = {
111  .demod_address = DTV5100_DEMOD_ADDR,
112  .no_tuner = 1,
113  .parallel_ts = 1,
114 };
115 
116 static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
117 {
118  adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119  &adap->dev->i2c_adap);
120  if (adap->fe_adap[0].fe == NULL)
121  return -EIO;
122 
123  /* disable i2c gate, or it won't work... is this safe? */
124  adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
125 
126  return 0;
127 }
128 
129 static struct qt1010_config dtv5100_qt1010_config = {
130  .i2c_address = DTV5100_TUNER_ADDR
131 };
132 
133 static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
134 {
135  return dvb_attach(qt1010_attach,
136  adap->fe_adap[0].fe, &adap->dev->i2c_adap,
137  &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
138 }
139 
140 /* DVB USB Driver stuff */
141 static struct dvb_usb_device_properties dtv5100_properties;
142 
143 static int dtv5100_probe(struct usb_interface *intf,
144  const struct usb_device_id *id)
145 {
146  int i, ret;
147  struct usb_device *udev = interface_to_usbdev(intf);
148 
149  /* initialize non qt1010/zl10353 part? */
150  for (i = 0; dtv5100_init[i].request; i++) {
151  ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
152  dtv5100_init[i].request,
154  dtv5100_init[i].value,
155  dtv5100_init[i].index, NULL, 0,
157  if (ret)
158  return ret;
159  }
160 
161  ret = dvb_usb_device_init(intf, &dtv5100_properties,
162  THIS_MODULE, NULL, adapter_nr);
163  if (ret)
164  return ret;
165 
166  return 0;
167 }
168 
169 static struct usb_device_id dtv5100_table[] = {
170  { USB_DEVICE(0x06be, 0xa232) },
171  { } /* Terminating entry */
172 };
173 MODULE_DEVICE_TABLE(usb, dtv5100_table);
174 
175 static struct dvb_usb_device_properties dtv5100_properties = {
177  .usb_ctrl = DEVICE_SPECIFIC,
178 
179  .size_of_priv = 0,
180 
181  .num_adapters = 1,
182  .adapter = {{
183  .num_frontends = 1,
184  .fe = {{
185  .frontend_attach = dtv5100_frontend_attach,
186  .tuner_attach = dtv5100_tuner_attach,
187 
188  .stream = {
189  .type = USB_BULK,
190  .count = 8,
191  .endpoint = 0x82,
192  .u = {
193  .bulk = {
194  .buffersize = 4096,
195  }
196  }
197  },
198  }},
199  } },
200 
201  .i2c_algo = &dtv5100_i2c_algo,
202 
203  .num_device_descs = 1,
204  .devices = {
205  {
206  .name = "AME DTV-5100 USB2.0 DVB-T",
207  .cold_ids = { NULL },
208  .warm_ids = { &dtv5100_table[0], NULL },
209  },
210  }
211 };
212 
213 static struct usb_driver dtv5100_driver = {
214  .name = "dvb_usb_dtv5100",
215  .probe = dtv5100_probe,
216  .disconnect = dvb_usb_device_exit,
217  .id_table = dtv5100_table,
218 };
219 
220 module_usb_driver(dtv5100_driver);
221 
224 MODULE_LICENSE("GPL");