1/*
2 *  Driver for the Conexant CX25821 PCIe bridge
3 *
4 *  Copyright (C) 2009 Conexant Systems Inc.
5 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *	Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26#include "cx25821.h"
27#include <linux/i2c.h>
28
29static unsigned int i2c_debug;
30module_param(i2c_debug, int, 0644);
31MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
32
33static unsigned int i2c_scan;
34module_param(i2c_scan, int, 0444);
35MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
36
37#define dprintk(level, fmt, arg...)					\
38do {									\
39	if (i2c_debug >= level)						\
40		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ##arg);	\
41} while (0)
42
43#define I2C_WAIT_DELAY 32
44#define I2C_WAIT_RETRY 64
45
46#define I2C_EXTEND  (1 << 3)
47#define I2C_NOSTOP  (1 << 4)
48
49static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
50{
51	struct cx25821_i2c *bus = i2c_adap->algo_data;
52	struct cx25821_dev *dev = bus->dev;
53	return cx_read(bus->reg_stat) & 0x01;
54}
55
56static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
57{
58	struct cx25821_i2c *bus = i2c_adap->algo_data;
59	struct cx25821_dev *dev = bus->dev;
60	return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
61}
62
63static int i2c_wait_done(struct i2c_adapter *i2c_adap)
64{
65	int count;
66
67	for (count = 0; count < I2C_WAIT_RETRY; count++) {
68		if (!i2c_is_busy(i2c_adap))
69			break;
70		udelay(I2C_WAIT_DELAY);
71	}
72
73	if (I2C_WAIT_RETRY == count)
74		return 0;
75
76	return 1;
77}
78
79static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
80			 const struct i2c_msg *msg, int joined_rlen)
81{
82	struct cx25821_i2c *bus = i2c_adap->algo_data;
83	struct cx25821_dev *dev = bus->dev;
84	u32 wdata, addr, ctrl;
85	int retval, cnt;
86
87	if (joined_rlen)
88		dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
89			msg->len, joined_rlen);
90	else
91		dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
92
93	/* Deal with i2c probe functions with zero payload */
94	if (msg->len == 0) {
95		cx_write(bus->reg_addr, msg->addr << 25);
96		cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
97
98		if (!i2c_wait_done(i2c_adap))
99			return -EIO;
100
101		if (!i2c_slave_did_ack(i2c_adap))
102			return -EIO;
103
104		dprintk(1, "%s(): returns 0\n", __func__);
105		return 0;
106	}
107
108	/* dev, reg + first byte */
109	addr = (msg->addr << 25) | msg->buf[0];
110	wdata = msg->buf[0];
111
112	ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
113
114	if (msg->len > 1)
115		ctrl |= I2C_NOSTOP | I2C_EXTEND;
116	else if (joined_rlen)
117		ctrl |= I2C_NOSTOP;
118
119	cx_write(bus->reg_addr, addr);
120	cx_write(bus->reg_wdata, wdata);
121	cx_write(bus->reg_ctrl, ctrl);
122
123	retval = i2c_wait_done(i2c_adap);
124	if (retval < 0)
125		goto err;
126
127	if (retval == 0)
128		goto eio;
129
130	if (i2c_debug) {
131		if (!(ctrl & I2C_NOSTOP))
132			printk(" >\n");
133	}
134
135	for (cnt = 1; cnt < msg->len; cnt++) {
136		/* following bytes */
137		wdata = msg->buf[cnt];
138		ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
139
140		if (cnt < msg->len - 1)
141			ctrl |= I2C_NOSTOP | I2C_EXTEND;
142		else if (joined_rlen)
143			ctrl |= I2C_NOSTOP;
144
145		cx_write(bus->reg_addr, addr);
146		cx_write(bus->reg_wdata, wdata);
147		cx_write(bus->reg_ctrl, ctrl);
148
149		retval = i2c_wait_done(i2c_adap);
150		if (retval < 0)
151			goto err;
152
153		if (retval == 0)
154			goto eio;
155
156		if (i2c_debug) {
157			dprintk(1, " %02x", msg->buf[cnt]);
158			if (!(ctrl & I2C_NOSTOP))
159				dprintk(1, " >\n");
160		}
161	}
162
163	return msg->len;
164
165eio:
166	retval = -EIO;
167err:
168	if (i2c_debug)
169		pr_err(" ERR: %d\n", retval);
170	return retval;
171}
172
173static int i2c_readbytes(struct i2c_adapter *i2c_adap,
174			 const struct i2c_msg *msg, int joined)
175{
176	struct cx25821_i2c *bus = i2c_adap->algo_data;
177	struct cx25821_dev *dev = bus->dev;
178	u32 ctrl, cnt;
179	int retval;
180
181	if (i2c_debug && !joined)
182		dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
183
184	/* Deal with i2c probe functions with zero payload */
185	if (msg->len == 0) {
186		cx_write(bus->reg_addr, msg->addr << 25);
187		cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
188		if (!i2c_wait_done(i2c_adap))
189			return -EIO;
190		if (!i2c_slave_did_ack(i2c_adap))
191			return -EIO;
192
193		dprintk(1, "%s(): returns 0\n", __func__);
194		return 0;
195	}
196
197	if (i2c_debug) {
198		if (joined)
199			dprintk(1, " R");
200		else
201			dprintk(1, " <R %02x", (msg->addr << 1) + 1);
202	}
203
204	for (cnt = 0; cnt < msg->len; cnt++) {
205
206		ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
207
208		if (cnt < msg->len - 1)
209			ctrl |= I2C_NOSTOP | I2C_EXTEND;
210
211		cx_write(bus->reg_addr, msg->addr << 25);
212		cx_write(bus->reg_ctrl, ctrl);
213
214		retval = i2c_wait_done(i2c_adap);
215		if (retval < 0)
216			goto err;
217		if (retval == 0)
218			goto eio;
219		msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
220
221		if (i2c_debug) {
222			dprintk(1, " %02x", msg->buf[cnt]);
223			if (!(ctrl & I2C_NOSTOP))
224				dprintk(1, " >\n");
225		}
226	}
227
228	return msg->len;
229eio:
230	retval = -EIO;
231err:
232	if (i2c_debug)
233		pr_err(" ERR: %d\n", retval);
234	return retval;
235}
236
237static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
238{
239	struct cx25821_i2c *bus = i2c_adap->algo_data;
240	struct cx25821_dev *dev = bus->dev;
241	int i, retval = 0;
242
243	dprintk(1, "%s(num = %d)\n", __func__, num);
244
245	for (i = 0; i < num; i++) {
246		dprintk(1, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
247			__func__, num, msgs[i].addr, msgs[i].len);
248
249		if (msgs[i].flags & I2C_M_RD) {
250			/* read */
251			retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
252		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
253			   msgs[i].addr == msgs[i + 1].addr) {
254			/* write then read from same address */
255			retval = i2c_sendbytes(i2c_adap, &msgs[i],
256					msgs[i + 1].len);
257
258			if (retval < 0)
259				goto err;
260			i++;
261			retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
262		} else {
263			/* write */
264			retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
265		}
266
267		if (retval < 0)
268			goto err;
269	}
270	return num;
271
272err:
273	return retval;
274}
275
276
277static u32 cx25821_functionality(struct i2c_adapter *adap)
278{
279	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA |
280		I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
281}
282
283static struct i2c_algorithm cx25821_i2c_algo_template = {
284	.master_xfer = i2c_xfer,
285	.functionality = cx25821_functionality,
286#ifdef NEED_ALGO_CONTROL
287	.algo_control = dummy_algo_control,
288#endif
289};
290
291static struct i2c_adapter cx25821_i2c_adap_template = {
292	.name = "cx25821",
293	.owner = THIS_MODULE,
294	.algo = &cx25821_i2c_algo_template,
295};
296
297static struct i2c_client cx25821_i2c_client_template = {
298	.name = "cx25821 internal",
299};
300
301/* init + register i2c adapter */
302int cx25821_i2c_register(struct cx25821_i2c *bus)
303{
304	struct cx25821_dev *dev = bus->dev;
305
306	dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
307
308	memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
309	       sizeof(bus->i2c_adap));
310	memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
311	       sizeof(bus->i2c_algo));
312	memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
313	       sizeof(bus->i2c_client));
314
315	bus->i2c_adap.dev.parent = &dev->pci->dev;
316
317	strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
318
319	bus->i2c_algo.data = bus;
320	bus->i2c_adap.algo_data = bus;
321	i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
322	i2c_add_adapter(&bus->i2c_adap);
323
324	bus->i2c_client.adapter = &bus->i2c_adap;
325
326	/* set up the I2c */
327	bus->i2c_client.addr = (0x88 >> 1);
328
329	return bus->i2c_rc;
330}
331
332int cx25821_i2c_unregister(struct cx25821_i2c *bus)
333{
334	i2c_del_adapter(&bus->i2c_adap);
335	return 0;
336}
337
338void cx25821_av_clk(struct cx25821_dev *dev, int enable)
339{
340	/* write 0 to bus 2 addr 0x144 via i2x_xfer() */
341	char buffer[3];
342	struct i2c_msg msg;
343	dprintk(1, "%s(enabled = %d)\n", __func__, enable);
344
345	/* Register 0x144 */
346	buffer[0] = 0x01;
347	buffer[1] = 0x44;
348	if (enable == 1)
349		buffer[2] = 0x05;
350	else
351		buffer[2] = 0x00;
352
353	msg.addr = 0x44;
354	msg.flags = I2C_M_TEN;
355	msg.len = 3;
356	msg.buf = buffer;
357
358	i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
359}
360
361int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
362{
363	struct i2c_client *client = &bus->i2c_client;
364	int retval = 0;
365	int v = 0;
366	u8 addr[2] = { 0, 0 };
367	u8 buf[4] = { 0, 0, 0, 0 };
368
369	struct i2c_msg msgs[2] = {
370		{
371			.addr = client->addr,
372			.flags = 0,
373			.len = 2,
374			.buf = addr,
375		}, {
376			.addr = client->addr,
377			.flags = I2C_M_RD,
378			.len = 4,
379			.buf = buf,
380		}
381	};
382
383	addr[0] = (reg_addr >> 8);
384	addr[1] = (reg_addr & 0xff);
385	msgs[0].addr = 0x44;
386	msgs[1].addr = 0x44;
387
388	retval = i2c_xfer(client->adapter, msgs, 2);
389
390	v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
391	*value = v;
392
393	return v;
394}
395
396int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
397{
398	struct i2c_client *client = &bus->i2c_client;
399	int retval = 0;
400	u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
401
402	struct i2c_msg msgs[1] = {
403		{
404			.addr = client->addr,
405			.flags = 0,
406			.len = 6,
407			.buf = buf,
408		}
409	};
410
411	buf[0] = reg_addr >> 8;
412	buf[1] = reg_addr & 0xff;
413	buf[5] = (value >> 24) & 0xff;
414	buf[4] = (value >> 16) & 0xff;
415	buf[3] = (value >> 8) & 0xff;
416	buf[2] = value & 0xff;
417	client->flags = 0;
418	msgs[0].addr = 0x44;
419
420	retval = i2c_xfer(client->adapter, msgs, 1);
421
422	return retval;
423}
424