• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Driver for the Auvitek AU0828 USB bridge
3  *
4  *  Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
5  *
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.
10  *
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  *
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 #include <linux/module.h>
23 #include <linux/moduleparam.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/io.h>
27 
28 #include "au0828.h"
29 
30 #include <media/v4l2-common.h>
31 
32 static int i2c_scan;
33 module_param(i2c_scan, int, 0444);
34 MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
35 
36 #define I2C_WAIT_DELAY 512
37 #define I2C_WAIT_RETRY 64
38 
i2c_slave_did_write_ack(struct i2c_adapter * i2c_adap)39 static inline int i2c_slave_did_write_ack(struct i2c_adapter *i2c_adap)
40 {
41 	struct au0828_dev *dev = i2c_adap->algo_data;
42 	return au0828_read(dev, REG_201) & 0x08 ? 0 : 1;
43 }
44 
i2c_slave_did_read_ack(struct i2c_adapter * i2c_adap)45 static inline int i2c_slave_did_read_ack(struct i2c_adapter *i2c_adap)
46 {
47 	struct au0828_dev *dev = i2c_adap->algo_data;
48 	return au0828_read(dev, REG_201) & 0x02 ? 0 : 1;
49 }
50 
i2c_wait_read_ack(struct i2c_adapter * i2c_adap)51 static int i2c_wait_read_ack(struct i2c_adapter *i2c_adap)
52 {
53 	int count;
54 
55 	for (count = 0; count < I2C_WAIT_RETRY; count++) {
56 		if (!i2c_slave_did_read_ack(i2c_adap))
57 			break;
58 		udelay(I2C_WAIT_DELAY);
59 	}
60 
61 	if (I2C_WAIT_RETRY == count)
62 		return 0;
63 
64 	return 1;
65 }
66 
i2c_is_read_busy(struct i2c_adapter * i2c_adap)67 static inline int i2c_is_read_busy(struct i2c_adapter *i2c_adap)
68 {
69 	struct au0828_dev *dev = i2c_adap->algo_data;
70 	return au0828_read(dev, REG_201) & 0x01 ? 0 : 1;
71 }
72 
i2c_wait_read_done(struct i2c_adapter * i2c_adap)73 static int i2c_wait_read_done(struct i2c_adapter *i2c_adap)
74 {
75 	int count;
76 
77 	for (count = 0; count < I2C_WAIT_RETRY; count++) {
78 		if (!i2c_is_read_busy(i2c_adap))
79 			break;
80 		udelay(I2C_WAIT_DELAY);
81 	}
82 
83 	if (I2C_WAIT_RETRY == count)
84 		return 0;
85 
86 	return 1;
87 }
88 
i2c_is_write_done(struct i2c_adapter * i2c_adap)89 static inline int i2c_is_write_done(struct i2c_adapter *i2c_adap)
90 {
91 	struct au0828_dev *dev = i2c_adap->algo_data;
92 	return au0828_read(dev, REG_201) & 0x04 ? 1 : 0;
93 }
94 
i2c_wait_write_done(struct i2c_adapter * i2c_adap)95 static int i2c_wait_write_done(struct i2c_adapter *i2c_adap)
96 {
97 	int count;
98 
99 	for (count = 0; count < I2C_WAIT_RETRY; count++) {
100 		if (i2c_is_write_done(i2c_adap))
101 			break;
102 		udelay(I2C_WAIT_DELAY);
103 	}
104 
105 	if (I2C_WAIT_RETRY == count)
106 		return 0;
107 
108 	return 1;
109 }
110 
i2c_is_busy(struct i2c_adapter * i2c_adap)111 static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
112 {
113 	struct au0828_dev *dev = i2c_adap->algo_data;
114 	return au0828_read(dev, REG_201) & 0x10 ? 1 : 0;
115 }
116 
i2c_wait_done(struct i2c_adapter * i2c_adap)117 static int i2c_wait_done(struct i2c_adapter *i2c_adap)
118 {
119 	int count;
120 
121 	for (count = 0; count < I2C_WAIT_RETRY; count++) {
122 		if (!i2c_is_busy(i2c_adap))
123 			break;
124 		udelay(I2C_WAIT_DELAY);
125 	}
126 
127 	if (I2C_WAIT_RETRY == count)
128 		return 0;
129 
130 	return 1;
131 }
132 
133 /* FIXME: Implement join handling correctly */
i2c_sendbytes(struct i2c_adapter * i2c_adap,const struct i2c_msg * msg,int joined_rlen)134 static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
135 	const struct i2c_msg *msg, int joined_rlen)
136 {
137 	int i, strobe = 0;
138 	struct au0828_dev *dev = i2c_adap->algo_data;
139 
140 	dprintk(4, "%s()\n", __func__);
141 
142 	au0828_write(dev, REG_2FF, 0x01);
143 	au0828_write(dev, REG_202, 0x07);
144 
145 	/* Hardware needs 8 bit addresses */
146 	au0828_write(dev, REG_203, msg->addr << 1);
147 
148 	dprintk(4, "SEND: %02x\n", msg->addr);
149 
150 	for (i = 0; i < msg->len;) {
151 
152 		dprintk(4, " %02x\n", msg->buf[i]);
153 
154 		au0828_write(dev, REG_205, msg->buf[i]);
155 
156 		strobe++;
157 		i++;
158 
159 		if ((strobe >= 4) || (i >= msg->len)) {
160 
161 			/* Strobe the byte into the bus */
162 			if (i < msg->len)
163 				au0828_write(dev, REG_200, 0x41);
164 			else
165 				au0828_write(dev, REG_200, 0x01);
166 
167 			/* Reset strobe trigger */
168 			strobe = 0;
169 
170 			if (!i2c_wait_write_done(i2c_adap))
171 				return -EIO;
172 
173 		}
174 
175 	}
176 	if (!i2c_wait_done(i2c_adap))
177 		return -EIO;
178 
179 	dprintk(4, "\n");
180 
181 	return msg->len;
182 }
183 
184 /* FIXME: Implement join handling correctly */
i2c_readbytes(struct i2c_adapter * i2c_adap,const struct i2c_msg * msg,int joined)185 static int i2c_readbytes(struct i2c_adapter *i2c_adap,
186 	const struct i2c_msg *msg, int joined)
187 {
188 	struct au0828_dev *dev = i2c_adap->algo_data;
189 	int i;
190 
191 	dprintk(4, "%s()\n", __func__);
192 
193 	au0828_write(dev, REG_2FF, 0x01);
194 	au0828_write(dev, REG_202, 0x07);
195 
196 	/* Hardware needs 8 bit addresses */
197 	au0828_write(dev, REG_203, msg->addr << 1);
198 
199 	dprintk(4, " RECV:\n");
200 
201 	/* Deal with i2c_scan */
202 	if (msg->len == 0) {
203 		au0828_write(dev, REG_200, 0x20);
204 		if (i2c_wait_read_ack(i2c_adap))
205 			return -EIO;
206 		return 0;
207 	}
208 
209 	for (i = 0; i < msg->len;) {
210 
211 		i++;
212 
213 		if (i < msg->len)
214 			au0828_write(dev, REG_200, 0x60);
215 		else
216 			au0828_write(dev, REG_200, 0x20);
217 
218 		if (!i2c_wait_read_done(i2c_adap))
219 			return -EIO;
220 
221 		msg->buf[i-1] = au0828_read(dev, REG_209) & 0xff;
222 
223 		dprintk(4, " %02x\n", msg->buf[i-1]);
224 	}
225 	if (!i2c_wait_done(i2c_adap))
226 		return -EIO;
227 
228 	dprintk(4, "\n");
229 
230 	return msg->len;
231 }
232 
i2c_xfer(struct i2c_adapter * i2c_adap,struct i2c_msg * msgs,int num)233 static int i2c_xfer(struct i2c_adapter *i2c_adap,
234 		    struct i2c_msg *msgs, int num)
235 {
236 	int i, retval = 0;
237 
238 	dprintk(4, "%s(num = %d)\n", __func__, num);
239 
240 	for (i = 0; i < num; i++) {
241 		dprintk(4, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
242 			__func__, num, msgs[i].addr, msgs[i].len);
243 		if (msgs[i].flags & I2C_M_RD) {
244 			/* read */
245 			retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
246 		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
247 			   msgs[i].addr == msgs[i + 1].addr) {
248 			/* write then read from same address */
249 			retval = i2c_sendbytes(i2c_adap, &msgs[i],
250 					       msgs[i + 1].len);
251 			if (retval < 0)
252 				goto err;
253 			i++;
254 			retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
255 		} else {
256 			/* write */
257 			retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
258 		}
259 		if (retval < 0)
260 			goto err;
261 	}
262 	return num;
263 
264 err:
265 	return retval;
266 }
267 
attach_inform(struct i2c_client * client)268 static int attach_inform(struct i2c_client *client)
269 {
270 	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
271 		client->driver->driver.name, client->addr, client->name);
272 
273 	if (!client->driver->command)
274 		return 0;
275 
276 	return 0;
277 }
278 
detach_inform(struct i2c_client * client)279 static int detach_inform(struct i2c_client *client)
280 {
281 	dprintk(1, "i2c detach [client=%s]\n", client->name);
282 
283 	return 0;
284 }
285 
au0828_call_i2c_clients(struct au0828_dev * dev,unsigned int cmd,void * arg)286 void au0828_call_i2c_clients(struct au0828_dev *dev,
287 			      unsigned int cmd, void *arg)
288 {
289 	if (dev->i2c_rc != 0)
290 		return;
291 
292 	i2c_clients_command(&dev->i2c_adap, cmd, arg);
293 }
294 
au0828_functionality(struct i2c_adapter * adap)295 static u32 au0828_functionality(struct i2c_adapter *adap)
296 {
297 	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
298 }
299 
300 static struct i2c_algorithm au0828_i2c_algo_template = {
301 	.master_xfer	= i2c_xfer,
302 	.functionality	= au0828_functionality,
303 };
304 
305 /* ----------------------------------------------------------------------- */
306 
307 static struct i2c_adapter au0828_i2c_adap_template = {
308 	.name              = DRIVER_NAME,
309 	.owner             = THIS_MODULE,
310 	.id                = I2C_HW_B_AU0828,
311 	.algo              = &au0828_i2c_algo_template,
312 	.class             = I2C_CLASS_TV_ANALOG,
313 	.client_register   = attach_inform,
314 	.client_unregister = detach_inform,
315 };
316 
317 static struct i2c_client au0828_i2c_client_template = {
318 	.name	= "au0828 internal",
319 };
320 
321 static char *i2c_devs[128] = {
322 	[0x8e >> 1] = "au8522",
323 	[0xa0 >> 1] = "eeprom",
324 	[0xc2 >> 1] = "tuner/xc5000",
325 };
326 
do_i2c_scan(char * name,struct i2c_client * c)327 static void do_i2c_scan(char *name, struct i2c_client *c)
328 {
329 	unsigned char buf;
330 	int i, rc;
331 
332 	for (i = 0; i < 128; i++) {
333 		c->addr = i;
334 		rc = i2c_master_recv(c, &buf, 0);
335 		if (rc < 0)
336 			continue;
337 		printk(KERN_INFO "%s: i2c scan: found device @ 0x%x  [%s]\n",
338 		       name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
339 	}
340 }
341 
342 /* init + register i2c algo-bit adapter */
au0828_i2c_register(struct au0828_dev * dev)343 int au0828_i2c_register(struct au0828_dev *dev)
344 {
345 	dprintk(1, "%s()\n", __func__);
346 
347 	memcpy(&dev->i2c_adap, &au0828_i2c_adap_template,
348 	       sizeof(dev->i2c_adap));
349 	memcpy(&dev->i2c_algo, &au0828_i2c_algo_template,
350 	       sizeof(dev->i2c_algo));
351 	memcpy(&dev->i2c_client, &au0828_i2c_client_template,
352 	       sizeof(dev->i2c_client));
353 
354 	dev->i2c_adap.dev.parent = &dev->usbdev->dev;
355 
356 	strlcpy(dev->i2c_adap.name, DRIVER_NAME,
357 		sizeof(dev->i2c_adap.name));
358 
359 	dev->i2c_algo.data = dev;
360 	dev->i2c_adap.algo_data = dev;
361 	i2c_set_adapdata(&dev->i2c_adap, dev);
362 	i2c_add_adapter(&dev->i2c_adap);
363 
364 	dev->i2c_client.adapter = &dev->i2c_adap;
365 
366 	if (0 == dev->i2c_rc) {
367 		printk(KERN_INFO "%s: i2c bus registered\n", DRIVER_NAME);
368 		if (i2c_scan)
369 			do_i2c_scan(DRIVER_NAME, &dev->i2c_client);
370 	} else
371 		printk(KERN_INFO "%s: i2c bus register FAILED\n", DRIVER_NAME);
372 
373 	return dev->i2c_rc;
374 }
375 
au0828_i2c_unregister(struct au0828_dev * dev)376 int au0828_i2c_unregister(struct au0828_dev *dev)
377 {
378 	i2c_del_adapter(&dev->i2c_adap);
379 	return 0;
380 }
381 
382