xref: /openbmc/linux/drivers/media/pci/ivtv/ivtv-i2c.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b285192aSMauro Carvalho Chehab /*
3b285192aSMauro Carvalho Chehab     I2C functions
4b285192aSMauro Carvalho Chehab     Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
5b285192aSMauro Carvalho Chehab     Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>
6b285192aSMauro Carvalho Chehab 
7b285192aSMauro Carvalho Chehab  */
8b285192aSMauro Carvalho Chehab 
9b285192aSMauro Carvalho Chehab /*
10b285192aSMauro Carvalho Chehab     This file includes an i2c implementation that was reverse engineered
11b285192aSMauro Carvalho Chehab     from the Hauppauge windows driver.  Older ivtv versions used i2c-algo-bit,
12b285192aSMauro Carvalho Chehab     which whilst fine under most circumstances, had trouble with the Zilog
13b285192aSMauro Carvalho Chehab     CPU on the PVR-150 which handles IR functions (occasional inability to
14b285192aSMauro Carvalho Chehab     communicate with the chip until it was reset) and also with the i2c
15b285192aSMauro Carvalho Chehab     bus being completely unreachable when multiple PVR cards were present.
16b285192aSMauro Carvalho Chehab 
17b285192aSMauro Carvalho Chehab     The implementation is very similar to i2c-algo-bit, but there are enough
18b285192aSMauro Carvalho Chehab     subtle differences that the two are hard to merge.  The general strategy
19b285192aSMauro Carvalho Chehab     employed by i2c-algo-bit is to use udelay() to implement the timing
20b285192aSMauro Carvalho Chehab     when putting out bits on the scl/sda lines.  The general strategy taken
21b285192aSMauro Carvalho Chehab     here is to poll the lines for state changes (see ivtv_waitscl and
22b285192aSMauro Carvalho Chehab     ivtv_waitsda).  In addition there are small delays at various locations
23b285192aSMauro Carvalho Chehab     which poll the SCL line 5 times (ivtv_scldelay).  I would guess that
24b285192aSMauro Carvalho Chehab     since this is memory mapped I/O that the length of those delays is tied
25b285192aSMauro Carvalho Chehab     to the PCI bus clock.  There is some extra code to do with recovery
26b285192aSMauro Carvalho Chehab     and retries.  Since it is not known what causes the actual i2c problems
27b285192aSMauro Carvalho Chehab     in the first place, the only goal if one was to attempt to use
28b285192aSMauro Carvalho Chehab     i2c-algo-bit would be to try to make it follow the same code path.
29b285192aSMauro Carvalho Chehab     This would be a lot of work, and I'm also not convinced that it would
30b285192aSMauro Carvalho Chehab     provide a generic benefit to i2c-algo-bit.  Therefore consider this
31b285192aSMauro Carvalho Chehab     an engineering solution -- not pretty, but it works.
32b285192aSMauro Carvalho Chehab 
33b285192aSMauro Carvalho Chehab     Some more general comments about what we are doing:
34b285192aSMauro Carvalho Chehab 
35b285192aSMauro Carvalho Chehab     The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA)
36b285192aSMauro Carvalho Chehab     lines.  To communicate on the bus (as a master, we don't act as a slave),
37b285192aSMauro Carvalho Chehab     we first initiate a start condition (ivtv_start).  We then write the
38b285192aSMauro Carvalho Chehab     address of the device that we want to communicate with, along with a flag
39b285192aSMauro Carvalho Chehab     that indicates whether this is a read or a write.  The slave then issues
40b285192aSMauro Carvalho Chehab     an ACK signal (ivtv_ack), which tells us that it is ready for reading /
41b285192aSMauro Carvalho Chehab     writing.  We then proceed with reading or writing (ivtv_read/ivtv_write),
42b285192aSMauro Carvalho Chehab     and finally issue a stop condition (ivtv_stop) to make the bus available
43b285192aSMauro Carvalho Chehab     to other masters.
44b285192aSMauro Carvalho Chehab 
45b285192aSMauro Carvalho Chehab     There is an additional form of transaction where a write may be
46b285192aSMauro Carvalho Chehab     immediately followed by a read.  In this case, there is no intervening
47b285192aSMauro Carvalho Chehab     stop condition.  (Only the msp3400 chip uses this method of data transfer).
48b285192aSMauro Carvalho Chehab  */
49b285192aSMauro Carvalho Chehab 
50b285192aSMauro Carvalho Chehab #include "ivtv-driver.h"
51b285192aSMauro Carvalho Chehab #include "ivtv-cards.h"
52b285192aSMauro Carvalho Chehab #include "ivtv-gpio.h"
53b285192aSMauro Carvalho Chehab #include "ivtv-i2c.h"
54d647f0b7SMauro Carvalho Chehab #include <media/drv-intf/cx25840.h>
55b285192aSMauro Carvalho Chehab 
56b285192aSMauro Carvalho Chehab /* i2c implementation for cx23415/6 chip, ivtv project.
57b285192aSMauro Carvalho Chehab  * Author: Kevin Thayer (nufan_wfk at yahoo.com)
58b285192aSMauro Carvalho Chehab  */
59b285192aSMauro Carvalho Chehab /* i2c stuff */
60b285192aSMauro Carvalho Chehab #define IVTV_REG_I2C_SETSCL_OFFSET 0x7000
61b285192aSMauro Carvalho Chehab #define IVTV_REG_I2C_SETSDA_OFFSET 0x7004
62b285192aSMauro Carvalho Chehab #define IVTV_REG_I2C_GETSCL_OFFSET 0x7008
63b285192aSMauro Carvalho Chehab #define IVTV_REG_I2C_GETSDA_OFFSET 0x700c
64b285192aSMauro Carvalho Chehab 
65b285192aSMauro Carvalho Chehab #define IVTV_CS53L32A_I2C_ADDR		0x11
66b285192aSMauro Carvalho Chehab #define IVTV_M52790_I2C_ADDR		0x48
67b285192aSMauro Carvalho Chehab #define IVTV_CX25840_I2C_ADDR		0x44
68b285192aSMauro Carvalho Chehab #define IVTV_SAA7115_I2C_ADDR		0x21
69b285192aSMauro Carvalho Chehab #define IVTV_SAA7127_I2C_ADDR		0x44
70b285192aSMauro Carvalho Chehab #define IVTV_SAA717x_I2C_ADDR		0x21
71b285192aSMauro Carvalho Chehab #define IVTV_MSP3400_I2C_ADDR		0x40
72b285192aSMauro Carvalho Chehab #define IVTV_HAUPPAUGE_I2C_ADDR		0x50
73b285192aSMauro Carvalho Chehab #define IVTV_WM8739_I2C_ADDR		0x1a
74b285192aSMauro Carvalho Chehab #define IVTV_WM8775_I2C_ADDR		0x1b
75b285192aSMauro Carvalho Chehab #define IVTV_TEA5767_I2C_ADDR		0x60
76b285192aSMauro Carvalho Chehab #define IVTV_UPD64031A_I2C_ADDR		0x12
77b285192aSMauro Carvalho Chehab #define IVTV_UPD64083_I2C_ADDR		0x5c
78b285192aSMauro Carvalho Chehab #define IVTV_VP27SMPX_I2C_ADDR		0x5b
79b285192aSMauro Carvalho Chehab #define IVTV_M52790_I2C_ADDR		0x48
80b285192aSMauro Carvalho Chehab #define IVTV_AVERMEDIA_IR_RX_I2C_ADDR	0x40
81b285192aSMauro Carvalho Chehab #define IVTV_HAUP_EXT_IR_RX_I2C_ADDR	0x1a
82b285192aSMauro Carvalho Chehab #define IVTV_HAUP_INT_IR_RX_I2C_ADDR	0x18
83b285192aSMauro Carvalho Chehab #define IVTV_Z8F0811_IR_TX_I2C_ADDR	0x70
84b285192aSMauro Carvalho Chehab #define IVTV_Z8F0811_IR_RX_I2C_ADDR	0x71
85b285192aSMauro Carvalho Chehab #define IVTV_ADAPTEC_IR_ADDR		0x6b
86b285192aSMauro Carvalho Chehab 
87b285192aSMauro Carvalho Chehab /* This array should match the IVTV_HW_ defines */
88*ed638b1dSMauro Carvalho Chehab static const u8 hw_addrs[IVTV_HW_MAX_BITS] = {
89b285192aSMauro Carvalho Chehab 	IVTV_CX25840_I2C_ADDR,
90b285192aSMauro Carvalho Chehab 	IVTV_SAA7115_I2C_ADDR,
91b285192aSMauro Carvalho Chehab 	IVTV_SAA7127_I2C_ADDR,
92b285192aSMauro Carvalho Chehab 	IVTV_MSP3400_I2C_ADDR,
93b285192aSMauro Carvalho Chehab 	0,
94b285192aSMauro Carvalho Chehab 	IVTV_WM8775_I2C_ADDR,
95b285192aSMauro Carvalho Chehab 	IVTV_CS53L32A_I2C_ADDR,
96b285192aSMauro Carvalho Chehab 	0,
97b285192aSMauro Carvalho Chehab 	IVTV_SAA7115_I2C_ADDR,
98b285192aSMauro Carvalho Chehab 	IVTV_UPD64031A_I2C_ADDR,
99b285192aSMauro Carvalho Chehab 	IVTV_UPD64083_I2C_ADDR,
100b285192aSMauro Carvalho Chehab 	IVTV_SAA717x_I2C_ADDR,
101b285192aSMauro Carvalho Chehab 	IVTV_WM8739_I2C_ADDR,
102b285192aSMauro Carvalho Chehab 	IVTV_VP27SMPX_I2C_ADDR,
103b285192aSMauro Carvalho Chehab 	IVTV_M52790_I2C_ADDR,
104b285192aSMauro Carvalho Chehab 	0,				/* IVTV_HW_GPIO dummy driver ID */
105b285192aSMauro Carvalho Chehab 	IVTV_AVERMEDIA_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_AVER */
106b285192aSMauro Carvalho Chehab 	IVTV_HAUP_EXT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
107b285192aSMauro Carvalho Chehab 	IVTV_HAUP_INT_IR_RX_I2C_ADDR,	/* IVTV_HW_I2C_IR_RX_HAUP_INT */
108ab5222edSSean Young 	IVTV_Z8F0811_IR_RX_I2C_ADDR,	/* IVTV_HW_Z8F0811_IR_HAUP */
109b285192aSMauro Carvalho Chehab 	IVTV_ADAPTEC_IR_ADDR,		/* IVTV_HW_I2C_IR_RX_ADAPTEC */
110b285192aSMauro Carvalho Chehab };
111b285192aSMauro Carvalho Chehab 
112b285192aSMauro Carvalho Chehab /* This array should match the IVTV_HW_ defines */
113*ed638b1dSMauro Carvalho Chehab static const char * const hw_devicenames[IVTV_HW_MAX_BITS] = {
114b285192aSMauro Carvalho Chehab 	"cx25840",
115b285192aSMauro Carvalho Chehab 	"saa7115",
116b285192aSMauro Carvalho Chehab 	"saa7127_auto",	/* saa7127 or saa7129 */
117b285192aSMauro Carvalho Chehab 	"msp3400",
118b285192aSMauro Carvalho Chehab 	"tuner",
119b285192aSMauro Carvalho Chehab 	"wm8775",
120b285192aSMauro Carvalho Chehab 	"cs53l32a",
121b285192aSMauro Carvalho Chehab 	"tveeprom",
122b285192aSMauro Carvalho Chehab 	"saa7114",
123b285192aSMauro Carvalho Chehab 	"upd64031a",
124b285192aSMauro Carvalho Chehab 	"upd64083",
125b285192aSMauro Carvalho Chehab 	"saa717x",
126b285192aSMauro Carvalho Chehab 	"wm8739",
127b285192aSMauro Carvalho Chehab 	"vp27smpx",
128b285192aSMauro Carvalho Chehab 	"m52790",
129b285192aSMauro Carvalho Chehab 	"gpio",
130b285192aSMauro Carvalho Chehab 	"ir_video",		/* IVTV_HW_I2C_IR_RX_AVER */
131b285192aSMauro Carvalho Chehab 	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_EXT */
132b285192aSMauro Carvalho Chehab 	"ir_video",		/* IVTV_HW_I2C_IR_RX_HAUP_INT */
133ab5222edSSean Young 	"ir_z8f0811_haup",	/* IVTV_HW_Z8F0811_IR_HAUP */
134b285192aSMauro Carvalho Chehab 	"ir_video",		/* IVTV_HW_I2C_IR_RX_ADAPTEC */
135b285192aSMauro Carvalho Chehab };
136b285192aSMauro Carvalho Chehab 
get_key_adaptec(struct IR_i2c * ir,enum rc_proto * protocol,u32 * scancode,u8 * toggle)1376d741bfeSSean Young static int get_key_adaptec(struct IR_i2c *ir, enum rc_proto *protocol,
1384dd9bb91SDavid Härdeman 			   u32 *scancode, u8 *toggle)
139b285192aSMauro Carvalho Chehab {
140b285192aSMauro Carvalho Chehab 	unsigned char keybuf[4];
141b285192aSMauro Carvalho Chehab 
142b285192aSMauro Carvalho Chehab 	keybuf[0] = 0x00;
143b285192aSMauro Carvalho Chehab 	i2c_master_send(ir->c, keybuf, 1);
144b285192aSMauro Carvalho Chehab 	/* poll IR chip */
145b285192aSMauro Carvalho Chehab 	if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) {
146b285192aSMauro Carvalho Chehab 		return 0;
147b285192aSMauro Carvalho Chehab 	}
148b285192aSMauro Carvalho Chehab 
149b285192aSMauro Carvalho Chehab 	/* key pressed ? */
150b285192aSMauro Carvalho Chehab 	if (keybuf[2] == 0xff)
151b285192aSMauro Carvalho Chehab 		return 0;
152b285192aSMauro Carvalho Chehab 
153b285192aSMauro Carvalho Chehab 	/* remove repeat bit */
154b285192aSMauro Carvalho Chehab 	keybuf[2] &= 0x7f;
155b285192aSMauro Carvalho Chehab 	keybuf[3] |= 0x80;
156b285192aSMauro Carvalho Chehab 
1576d741bfeSSean Young 	*protocol = RC_PROTO_UNKNOWN;
1584dd9bb91SDavid Härdeman 	*scancode = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24;
1594dd9bb91SDavid Härdeman 	*toggle = 0;
160b285192aSMauro Carvalho Chehab 	return 1;
161b285192aSMauro Carvalho Chehab }
162b285192aSMauro Carvalho Chehab 
ivtv_i2c_new_ir(struct ivtv * itv,u32 hw,const char * type,u8 addr)163b285192aSMauro Carvalho Chehab static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
164b285192aSMauro Carvalho Chehab {
165b285192aSMauro Carvalho Chehab 	struct i2c_board_info info;
166b285192aSMauro Carvalho Chehab 	struct i2c_adapter *adap = &itv->i2c_adap;
167b285192aSMauro Carvalho Chehab 	struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
168b285192aSMauro Carvalho Chehab 	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
169b285192aSMauro Carvalho Chehab 
170b285192aSMauro Carvalho Chehab 	/* Only allow one IR receiver to be registered per board */
171ab5222edSSean Young 	if (itv->hw_flags & IVTV_HW_IR_ANY)
172b285192aSMauro Carvalho Chehab 		return -1;
173b285192aSMauro Carvalho Chehab 
174b285192aSMauro Carvalho Chehab 	/* Our default information for ir-kbd-i2c.c to use */
175b285192aSMauro Carvalho Chehab 	switch (hw) {
176b285192aSMauro Carvalho Chehab 	case IVTV_HW_I2C_IR_RX_AVER:
177b285192aSMauro Carvalho Chehab 		init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS;
178b285192aSMauro Carvalho Chehab 		init_data->internal_get_key_func =
179b285192aSMauro Carvalho Chehab 					IR_KBD_GET_KEY_AVERMEDIA_CARDBUS;
1806d741bfeSSean Young 		init_data->type = RC_PROTO_BIT_OTHER;
181b285192aSMauro Carvalho Chehab 		init_data->name = "AVerMedia AVerTV card";
182b285192aSMauro Carvalho Chehab 		break;
183b285192aSMauro Carvalho Chehab 	case IVTV_HW_I2C_IR_RX_HAUP_EXT:
184b285192aSMauro Carvalho Chehab 	case IVTV_HW_I2C_IR_RX_HAUP_INT:
185b285192aSMauro Carvalho Chehab 		init_data->ir_codes = RC_MAP_HAUPPAUGE;
186b285192aSMauro Carvalho Chehab 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
1876d741bfeSSean Young 		init_data->type = RC_PROTO_BIT_RC5;
188b285192aSMauro Carvalho Chehab 		init_data->name = itv->card_name;
189b285192aSMauro Carvalho Chehab 		break;
190ab5222edSSean Young 	case IVTV_HW_Z8F0811_IR_HAUP:
191b285192aSMauro Carvalho Chehab 		/* Default to grey remote */
192b285192aSMauro Carvalho Chehab 		init_data->ir_codes = RC_MAP_HAUPPAUGE;
193b285192aSMauro Carvalho Chehab 		init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
1946d741bfeSSean Young 		init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
1956d741bfeSSean Young 							RC_PROTO_BIT_RC6_6A_32;
196b285192aSMauro Carvalho Chehab 		init_data->name = itv->card_name;
197b285192aSMauro Carvalho Chehab 		break;
198b285192aSMauro Carvalho Chehab 	case IVTV_HW_I2C_IR_RX_ADAPTEC:
199b285192aSMauro Carvalho Chehab 		init_data->get_key = get_key_adaptec;
200b285192aSMauro Carvalho Chehab 		init_data->name = itv->card_name;
201b285192aSMauro Carvalho Chehab 		/* FIXME: The protocol and RC_MAP needs to be corrected */
202b285192aSMauro Carvalho Chehab 		init_data->ir_codes = RC_MAP_EMPTY;
2036d741bfeSSean Young 		init_data->type = RC_PROTO_BIT_UNKNOWN;
204b285192aSMauro Carvalho Chehab 		break;
205b285192aSMauro Carvalho Chehab 	}
206b285192aSMauro Carvalho Chehab 
207b285192aSMauro Carvalho Chehab 	memset(&info, 0, sizeof(struct i2c_board_info));
208b285192aSMauro Carvalho Chehab 	info.platform_data = init_data;
209c0decac1SMauro Carvalho Chehab 	strscpy(info.type, type, I2C_NAME_SIZE);
210b285192aSMauro Carvalho Chehab 
2110f9be034SWolfram Sang 	return IS_ERR(i2c_new_scanned_device(adap, &info, addr_list, NULL)) ?
212b285192aSMauro Carvalho Chehab 	       -1 : 0;
213b285192aSMauro Carvalho Chehab }
214b285192aSMauro Carvalho Chehab 
215b285192aSMauro Carvalho Chehab /* Instantiate the IR receiver device using probing -- undesirable */
ivtv_i2c_new_ir_legacy(struct ivtv * itv)2160f9be034SWolfram Sang void ivtv_i2c_new_ir_legacy(struct ivtv *itv)
217b285192aSMauro Carvalho Chehab {
218b285192aSMauro Carvalho Chehab 	struct i2c_board_info info;
219b285192aSMauro Carvalho Chehab 	/*
220b285192aSMauro Carvalho Chehab 	 * The external IR receiver is at i2c address 0x34.
221b285192aSMauro Carvalho Chehab 	 * The internal IR receiver is at i2c address 0x30.
222b285192aSMauro Carvalho Chehab 	 *
223b285192aSMauro Carvalho Chehab 	 * In theory, both can be fitted, and Hauppauge suggests an external
224b285192aSMauro Carvalho Chehab 	 * overrides an internal.  That's why we probe 0x1a (~0x34) first. CB
225b285192aSMauro Carvalho Chehab 	 *
226b285192aSMauro Carvalho Chehab 	 * Some of these addresses we probe may collide with other i2c address
227b285192aSMauro Carvalho Chehab 	 * allocations, so this function must be called after all other i2c
228b285192aSMauro Carvalho Chehab 	 * devices we care about are registered.
229b285192aSMauro Carvalho Chehab 	 */
230db6df013SColin Ian King 	static const unsigned short addr_list[] = {
231b285192aSMauro Carvalho Chehab 		0x1a,	/* Hauppauge IR external - collides with WM8739 */
232b285192aSMauro Carvalho Chehab 		0x18,	/* Hauppauge IR internal */
233b285192aSMauro Carvalho Chehab 		I2C_CLIENT_END
234b285192aSMauro Carvalho Chehab 	};
235b285192aSMauro Carvalho Chehab 
236b285192aSMauro Carvalho Chehab 	memset(&info, 0, sizeof(struct i2c_board_info));
237c0decac1SMauro Carvalho Chehab 	strscpy(info.type, "ir_video", I2C_NAME_SIZE);
2380f9be034SWolfram Sang 	i2c_new_scanned_device(&itv->i2c_adap, &info, addr_list, NULL);
239b285192aSMauro Carvalho Chehab }
240b285192aSMauro Carvalho Chehab 
ivtv_i2c_register(struct ivtv * itv,unsigned idx)241b285192aSMauro Carvalho Chehab int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
242b285192aSMauro Carvalho Chehab {
243b285192aSMauro Carvalho Chehab 	struct i2c_adapter *adap = &itv->i2c_adap;
244*ed638b1dSMauro Carvalho Chehab 	struct v4l2_subdev *sd;
245*ed638b1dSMauro Carvalho Chehab 	const char *type;
246*ed638b1dSMauro Carvalho Chehab 	u32 hw;
247*ed638b1dSMauro Carvalho Chehab 
248*ed638b1dSMauro Carvalho Chehab 	if (idx >= IVTV_HW_MAX_BITS)
249*ed638b1dSMauro Carvalho Chehab 		return -ENODEV;
250*ed638b1dSMauro Carvalho Chehab 
251*ed638b1dSMauro Carvalho Chehab 	type = hw_devicenames[idx];
252*ed638b1dSMauro Carvalho Chehab 	hw = 1 << idx;
253b285192aSMauro Carvalho Chehab 
254b285192aSMauro Carvalho Chehab 	if (hw == IVTV_HW_TUNER) {
255b285192aSMauro Carvalho Chehab 		/* special tuner handling */
256b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
257b285192aSMauro Carvalho Chehab 				itv->card_i2c->radio);
258b285192aSMauro Carvalho Chehab 		if (sd)
259b285192aSMauro Carvalho Chehab 			sd->grp_id = 1 << idx;
260b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
261b285192aSMauro Carvalho Chehab 				itv->card_i2c->demod);
262b285192aSMauro Carvalho Chehab 		if (sd)
263b285192aSMauro Carvalho Chehab 			sd->grp_id = 1 << idx;
264b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0,
265b285192aSMauro Carvalho Chehab 				itv->card_i2c->tv);
266b285192aSMauro Carvalho Chehab 		if (sd)
267b285192aSMauro Carvalho Chehab 			sd->grp_id = 1 << idx;
268b285192aSMauro Carvalho Chehab 		return sd ? 0 : -1;
269b285192aSMauro Carvalho Chehab 	}
270b285192aSMauro Carvalho Chehab 
271b285192aSMauro Carvalho Chehab 	if (hw & IVTV_HW_IR_ANY)
272b285192aSMauro Carvalho Chehab 		return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]);
273b285192aSMauro Carvalho Chehab 
274b285192aSMauro Carvalho Chehab 	/* Is it not an I2C device or one we do not wish to register? */
275b285192aSMauro Carvalho Chehab 	if (!hw_addrs[idx])
276b285192aSMauro Carvalho Chehab 		return -1;
277b285192aSMauro Carvalho Chehab 
278b285192aSMauro Carvalho Chehab 	/* It's an I2C device other than an analog tuner or IR chip */
279b285192aSMauro Carvalho Chehab 	if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
280b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
281b285192aSMauro Carvalho Chehab 				adap, type, 0, I2C_ADDRS(hw_addrs[idx]));
282b285192aSMauro Carvalho Chehab 	} else if (hw == IVTV_HW_CX25840) {
283b285192aSMauro Carvalho Chehab 		struct cx25840_platform_data pdata;
284b285192aSMauro Carvalho Chehab 		struct i2c_board_info cx25840_info = {
285b285192aSMauro Carvalho Chehab 			.type = "cx25840",
286b285192aSMauro Carvalho Chehab 			.addr = hw_addrs[idx],
287b285192aSMauro Carvalho Chehab 			.platform_data = &pdata,
288b285192aSMauro Carvalho Chehab 		};
289b285192aSMauro Carvalho Chehab 
290c928d454SMaciej S. Szmigiero 		memset(&pdata, 0, sizeof(pdata));
291b285192aSMauro Carvalho Chehab 		pdata.pvr150_workaround = itv->pvr150_workaround;
292b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap,
293b285192aSMauro Carvalho Chehab 				&cx25840_info, NULL);
294b285192aSMauro Carvalho Chehab 	} else {
295b285192aSMauro Carvalho Chehab 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
296b285192aSMauro Carvalho Chehab 				adap, type, hw_addrs[idx], NULL);
297b285192aSMauro Carvalho Chehab 	}
298b285192aSMauro Carvalho Chehab 	if (sd)
299b285192aSMauro Carvalho Chehab 		sd->grp_id = 1 << idx;
300b285192aSMauro Carvalho Chehab 	return sd ? 0 : -1;
301b285192aSMauro Carvalho Chehab }
302b285192aSMauro Carvalho Chehab 
ivtv_find_hw(struct ivtv * itv,u32 hw)303b285192aSMauro Carvalho Chehab struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
304b285192aSMauro Carvalho Chehab {
305b285192aSMauro Carvalho Chehab 	struct v4l2_subdev *result = NULL;
306b285192aSMauro Carvalho Chehab 	struct v4l2_subdev *sd;
307b285192aSMauro Carvalho Chehab 
308b285192aSMauro Carvalho Chehab 	spin_lock(&itv->v4l2_dev.lock);
309b285192aSMauro Carvalho Chehab 	v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
310b285192aSMauro Carvalho Chehab 		if (sd->grp_id == hw) {
311b285192aSMauro Carvalho Chehab 			result = sd;
312b285192aSMauro Carvalho Chehab 			break;
313b285192aSMauro Carvalho Chehab 		}
314b285192aSMauro Carvalho Chehab 	}
315b285192aSMauro Carvalho Chehab 	spin_unlock(&itv->v4l2_dev.lock);
316b285192aSMauro Carvalho Chehab 	return result;
317b285192aSMauro Carvalho Chehab }
318b285192aSMauro Carvalho Chehab 
319b285192aSMauro Carvalho Chehab /* Set the serial clock line to the desired state */
ivtv_setscl(struct ivtv * itv,int state)320b285192aSMauro Carvalho Chehab static void ivtv_setscl(struct ivtv *itv, int state)
321b285192aSMauro Carvalho Chehab {
322b285192aSMauro Carvalho Chehab 	/* write them out */
323b285192aSMauro Carvalho Chehab 	/* write bits are inverted */
324b285192aSMauro Carvalho Chehab 	write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET);
325b285192aSMauro Carvalho Chehab }
326b285192aSMauro Carvalho Chehab 
327b285192aSMauro Carvalho Chehab /* Set the serial data line to the desired state */
ivtv_setsda(struct ivtv * itv,int state)328b285192aSMauro Carvalho Chehab static void ivtv_setsda(struct ivtv *itv, int state)
329b285192aSMauro Carvalho Chehab {
330b285192aSMauro Carvalho Chehab 	/* write them out */
331b285192aSMauro Carvalho Chehab 	/* write bits are inverted */
332b285192aSMauro Carvalho Chehab 	write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET);
333b285192aSMauro Carvalho Chehab }
334b285192aSMauro Carvalho Chehab 
335b285192aSMauro Carvalho Chehab /* Read the serial clock line */
ivtv_getscl(struct ivtv * itv)336b285192aSMauro Carvalho Chehab static int ivtv_getscl(struct ivtv *itv)
337b285192aSMauro Carvalho Chehab {
338b285192aSMauro Carvalho Chehab 	return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
339b285192aSMauro Carvalho Chehab }
340b285192aSMauro Carvalho Chehab 
341b285192aSMauro Carvalho Chehab /* Read the serial data line */
ivtv_getsda(struct ivtv * itv)342b285192aSMauro Carvalho Chehab static int ivtv_getsda(struct ivtv *itv)
343b285192aSMauro Carvalho Chehab {
344b285192aSMauro Carvalho Chehab 	return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
345b285192aSMauro Carvalho Chehab }
346b285192aSMauro Carvalho Chehab 
347b285192aSMauro Carvalho Chehab /* Implement a short delay by polling the serial clock line */
ivtv_scldelay(struct ivtv * itv)348b285192aSMauro Carvalho Chehab static void ivtv_scldelay(struct ivtv *itv)
349b285192aSMauro Carvalho Chehab {
350b285192aSMauro Carvalho Chehab 	int i;
351b285192aSMauro Carvalho Chehab 
352b285192aSMauro Carvalho Chehab 	for (i = 0; i < 5; ++i)
353b285192aSMauro Carvalho Chehab 		ivtv_getscl(itv);
354b285192aSMauro Carvalho Chehab }
355b285192aSMauro Carvalho Chehab 
356b285192aSMauro Carvalho Chehab /* Wait for the serial clock line to become set to a specific value */
ivtv_waitscl(struct ivtv * itv,int val)357b285192aSMauro Carvalho Chehab static int ivtv_waitscl(struct ivtv *itv, int val)
358b285192aSMauro Carvalho Chehab {
359b285192aSMauro Carvalho Chehab 	int i;
360b285192aSMauro Carvalho Chehab 
361b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
362b285192aSMauro Carvalho Chehab 	for (i = 0; i < 1000; ++i) {
363b285192aSMauro Carvalho Chehab 		if (ivtv_getscl(itv) == val)
364b285192aSMauro Carvalho Chehab 			return 1;
365b285192aSMauro Carvalho Chehab 	}
366b285192aSMauro Carvalho Chehab 	return 0;
367b285192aSMauro Carvalho Chehab }
368b285192aSMauro Carvalho Chehab 
369b285192aSMauro Carvalho Chehab /* Wait for the serial data line to become set to a specific value */
ivtv_waitsda(struct ivtv * itv,int val)370b285192aSMauro Carvalho Chehab static int ivtv_waitsda(struct ivtv *itv, int val)
371b285192aSMauro Carvalho Chehab {
372b285192aSMauro Carvalho Chehab 	int i;
373b285192aSMauro Carvalho Chehab 
374b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
375b285192aSMauro Carvalho Chehab 	for (i = 0; i < 1000; ++i) {
376b285192aSMauro Carvalho Chehab 		if (ivtv_getsda(itv) == val)
377b285192aSMauro Carvalho Chehab 			return 1;
378b285192aSMauro Carvalho Chehab 	}
379b285192aSMauro Carvalho Chehab 	return 0;
380b285192aSMauro Carvalho Chehab }
381b285192aSMauro Carvalho Chehab 
382b285192aSMauro Carvalho Chehab /* Wait for the slave to issue an ACK */
ivtv_ack(struct ivtv * itv)383b285192aSMauro Carvalho Chehab static int ivtv_ack(struct ivtv *itv)
384b285192aSMauro Carvalho Chehab {
385b285192aSMauro Carvalho Chehab 	int ret = 0;
386b285192aSMauro Carvalho Chehab 
387b285192aSMauro Carvalho Chehab 	if (ivtv_getscl(itv) == 1) {
388b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n");
389b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 0);
390b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 0)) {
391b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n");
392b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
393b285192aSMauro Carvalho Chehab 		}
394b285192aSMauro Carvalho Chehab 	}
395b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 1);
396b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
397b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 1);
398b285192aSMauro Carvalho Chehab 	if (!ivtv_waitsda(itv, 0)) {
399b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("Slave did not ack\n");
400b285192aSMauro Carvalho Chehab 		ret = -EREMOTEIO;
401b285192aSMauro Carvalho Chehab 	}
402b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 0);
403b285192aSMauro Carvalho Chehab 	if (!ivtv_waitscl(itv, 0)) {
404b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n");
405b285192aSMauro Carvalho Chehab 		ret = -EREMOTEIO;
406b285192aSMauro Carvalho Chehab 	}
407b285192aSMauro Carvalho Chehab 	return ret;
408b285192aSMauro Carvalho Chehab }
409b285192aSMauro Carvalho Chehab 
410b285192aSMauro Carvalho Chehab /* Write a single byte to the i2c bus and wait for the slave to ACK */
ivtv_sendbyte(struct ivtv * itv,unsigned char byte)411b285192aSMauro Carvalho Chehab static int ivtv_sendbyte(struct ivtv *itv, unsigned char byte)
412b285192aSMauro Carvalho Chehab {
413b285192aSMauro Carvalho Chehab 	int i, bit;
414b285192aSMauro Carvalho Chehab 
415b285192aSMauro Carvalho Chehab 	IVTV_DEBUG_HI_I2C("write %x\n",byte);
416b285192aSMauro Carvalho Chehab 	for (i = 0; i < 8; ++i, byte<<=1) {
417b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 0);
418b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 0)) {
419b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("Error setting SCL low\n");
420b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
421b285192aSMauro Carvalho Chehab 		}
422b285192aSMauro Carvalho Chehab 		bit = (byte>>7)&1;
423b285192aSMauro Carvalho Chehab 		ivtv_setsda(itv, bit);
424b285192aSMauro Carvalho Chehab 		if (!ivtv_waitsda(itv, bit)) {
425b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("Error setting SDA\n");
426b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
427b285192aSMauro Carvalho Chehab 		}
428b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 1);
429b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 1)) {
430b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("Slave not ready for bit\n");
431b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
432b285192aSMauro Carvalho Chehab 		}
433b285192aSMauro Carvalho Chehab 	}
434b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 0);
435b285192aSMauro Carvalho Chehab 	if (!ivtv_waitscl(itv, 0)) {
436b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("Error setting SCL low\n");
437b285192aSMauro Carvalho Chehab 		return -EREMOTEIO;
438b285192aSMauro Carvalho Chehab 	}
439b285192aSMauro Carvalho Chehab 	return ivtv_ack(itv);
440b285192aSMauro Carvalho Chehab }
441b285192aSMauro Carvalho Chehab 
442b285192aSMauro Carvalho Chehab /* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the
443b285192aSMauro Carvalho Chehab    final byte) */
ivtv_readbyte(struct ivtv * itv,unsigned char * byte,int nack)444b285192aSMauro Carvalho Chehab static int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack)
445b285192aSMauro Carvalho Chehab {
446b285192aSMauro Carvalho Chehab 	int i;
447b285192aSMauro Carvalho Chehab 
448b285192aSMauro Carvalho Chehab 	*byte = 0;
449b285192aSMauro Carvalho Chehab 
450b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 1);
451b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
452b285192aSMauro Carvalho Chehab 	for (i = 0; i < 8; ++i) {
453b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 0);
454b285192aSMauro Carvalho Chehab 		ivtv_scldelay(itv);
455b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 1);
456b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 1)) {
457b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("Error setting SCL high\n");
458b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
459b285192aSMauro Carvalho Chehab 		}
460b285192aSMauro Carvalho Chehab 		*byte = ((*byte)<<1)|ivtv_getsda(itv);
461b285192aSMauro Carvalho Chehab 	}
462b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 0);
463b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
464b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, nack);
465b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
466b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 1);
467b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
468b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 0);
469b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
470b285192aSMauro Carvalho Chehab 	IVTV_DEBUG_HI_I2C("read %x\n",*byte);
471b285192aSMauro Carvalho Chehab 	return 0;
472b285192aSMauro Carvalho Chehab }
473b285192aSMauro Carvalho Chehab 
474b285192aSMauro Carvalho Chehab /* Issue a start condition on the i2c bus to alert slaves to prepare for
475b285192aSMauro Carvalho Chehab    an address write */
ivtv_start(struct ivtv * itv)476b285192aSMauro Carvalho Chehab static int ivtv_start(struct ivtv *itv)
477b285192aSMauro Carvalho Chehab {
478b285192aSMauro Carvalho Chehab 	int sda;
479b285192aSMauro Carvalho Chehab 
480b285192aSMauro Carvalho Chehab 	sda = ivtv_getsda(itv);
481b285192aSMauro Carvalho Chehab 	if (sda != 1) {
482b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_HI_I2C("SDA was low at start\n");
483b285192aSMauro Carvalho Chehab 		ivtv_setsda(itv, 1);
484b285192aSMauro Carvalho Chehab 		if (!ivtv_waitsda(itv, 1)) {
485b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("SDA stuck low\n");
486b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
487b285192aSMauro Carvalho Chehab 		}
488b285192aSMauro Carvalho Chehab 	}
489b285192aSMauro Carvalho Chehab 	if (ivtv_getscl(itv) != 1) {
490b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 1);
491b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 1)) {
492b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("SCL stuck low at start\n");
493b285192aSMauro Carvalho Chehab 			return -EREMOTEIO;
494b285192aSMauro Carvalho Chehab 		}
495b285192aSMauro Carvalho Chehab 	}
496b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 0);
497b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
498b285192aSMauro Carvalho Chehab 	return 0;
499b285192aSMauro Carvalho Chehab }
500b285192aSMauro Carvalho Chehab 
501b285192aSMauro Carvalho Chehab /* Issue a stop condition on the i2c bus to release it */
ivtv_stop(struct ivtv * itv)502b285192aSMauro Carvalho Chehab static int ivtv_stop(struct ivtv *itv)
503b285192aSMauro Carvalho Chehab {
504b285192aSMauro Carvalho Chehab 	int i;
505b285192aSMauro Carvalho Chehab 
506b285192aSMauro Carvalho Chehab 	if (ivtv_getscl(itv) != 0) {
507b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_HI_I2C("SCL not low when stopping\n");
508b285192aSMauro Carvalho Chehab 		ivtv_setscl(itv, 0);
509b285192aSMauro Carvalho Chehab 		if (!ivtv_waitscl(itv, 0)) {
510b285192aSMauro Carvalho Chehab 			IVTV_DEBUG_I2C("SCL could not be set low\n");
511b285192aSMauro Carvalho Chehab 		}
512b285192aSMauro Carvalho Chehab 	}
513b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 0);
514b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
515b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 1);
516b285192aSMauro Carvalho Chehab 	if (!ivtv_waitscl(itv, 1)) {
517b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("SCL could not be set high\n");
518b285192aSMauro Carvalho Chehab 		return -EREMOTEIO;
519b285192aSMauro Carvalho Chehab 	}
520b285192aSMauro Carvalho Chehab 	ivtv_scldelay(itv);
521b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 1);
522b285192aSMauro Carvalho Chehab 	if (!ivtv_waitsda(itv, 1)) {
523b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("resetting I2C\n");
524b285192aSMauro Carvalho Chehab 		for (i = 0; i < 16; ++i) {
525b285192aSMauro Carvalho Chehab 			ivtv_setscl(itv, 0);
526b285192aSMauro Carvalho Chehab 			ivtv_scldelay(itv);
527b285192aSMauro Carvalho Chehab 			ivtv_setscl(itv, 1);
528b285192aSMauro Carvalho Chehab 			ivtv_scldelay(itv);
529b285192aSMauro Carvalho Chehab 			ivtv_setsda(itv, 1);
530b285192aSMauro Carvalho Chehab 		}
531b285192aSMauro Carvalho Chehab 		ivtv_waitsda(itv, 1);
532b285192aSMauro Carvalho Chehab 		return -EREMOTEIO;
533b285192aSMauro Carvalho Chehab 	}
534b285192aSMauro Carvalho Chehab 	return 0;
535b285192aSMauro Carvalho Chehab }
536b285192aSMauro Carvalho Chehab 
537b285192aSMauro Carvalho Chehab /* Write a message to the given i2c slave.  do_stop may be 0 to prevent
538b285192aSMauro Carvalho Chehab    issuing the i2c stop condition (when following with a read) */
ivtv_write(struct ivtv * itv,unsigned char addr,unsigned char * data,u32 len,int do_stop)539b285192aSMauro Carvalho Chehab static int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop)
540b285192aSMauro Carvalho Chehab {
541b285192aSMauro Carvalho Chehab 	int retry, ret = -EREMOTEIO;
542b285192aSMauro Carvalho Chehab 	u32 i;
543b285192aSMauro Carvalho Chehab 
544b285192aSMauro Carvalho Chehab 	for (retry = 0; ret != 0 && retry < 8; ++retry) {
545b285192aSMauro Carvalho Chehab 		ret = ivtv_start(itv);
546b285192aSMauro Carvalho Chehab 
547b285192aSMauro Carvalho Chehab 		if (ret == 0) {
548b285192aSMauro Carvalho Chehab 			ret = ivtv_sendbyte(itv, addr<<1);
549b285192aSMauro Carvalho Chehab 			for (i = 0; ret == 0 && i < len; ++i)
550b285192aSMauro Carvalho Chehab 				ret = ivtv_sendbyte(itv, data[i]);
551b285192aSMauro Carvalho Chehab 		}
552b285192aSMauro Carvalho Chehab 		if (ret != 0 || do_stop) {
553b285192aSMauro Carvalho Chehab 			ivtv_stop(itv);
554b285192aSMauro Carvalho Chehab 		}
555b285192aSMauro Carvalho Chehab 	}
556b285192aSMauro Carvalho Chehab 	if (ret)
557b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("i2c write to %x failed\n", addr);
558b285192aSMauro Carvalho Chehab 	return ret;
559b285192aSMauro Carvalho Chehab }
560b285192aSMauro Carvalho Chehab 
561b285192aSMauro Carvalho Chehab /* Read data from the given i2c slave.  A stop condition is always issued. */
ivtv_read(struct ivtv * itv,unsigned char addr,unsigned char * data,u32 len)562b285192aSMauro Carvalho Chehab static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len)
563b285192aSMauro Carvalho Chehab {
564b285192aSMauro Carvalho Chehab 	int retry, ret = -EREMOTEIO;
565b285192aSMauro Carvalho Chehab 	u32 i;
566b285192aSMauro Carvalho Chehab 
567b285192aSMauro Carvalho Chehab 	for (retry = 0; ret != 0 && retry < 8; ++retry) {
568b285192aSMauro Carvalho Chehab 		ret = ivtv_start(itv);
569b285192aSMauro Carvalho Chehab 		if (ret == 0)
570b285192aSMauro Carvalho Chehab 			ret = ivtv_sendbyte(itv, (addr << 1) | 1);
571b285192aSMauro Carvalho Chehab 		for (i = 0; ret == 0 && i < len; ++i) {
572b285192aSMauro Carvalho Chehab 			ret = ivtv_readbyte(itv, &data[i], i == len - 1);
573b285192aSMauro Carvalho Chehab 		}
574b285192aSMauro Carvalho Chehab 		ivtv_stop(itv);
575b285192aSMauro Carvalho Chehab 	}
576b285192aSMauro Carvalho Chehab 	if (ret)
577b285192aSMauro Carvalho Chehab 		IVTV_DEBUG_I2C("i2c read from %x failed\n", addr);
578b285192aSMauro Carvalho Chehab 	return ret;
579b285192aSMauro Carvalho Chehab }
580b285192aSMauro Carvalho Chehab 
581b285192aSMauro Carvalho Chehab /* Kernel i2c transfer implementation.  Takes a number of messages to be read
582b285192aSMauro Carvalho Chehab    or written.  If a read follows a write, this will occur without an
583b285192aSMauro Carvalho Chehab    intervening stop condition */
ivtv_xfer(struct i2c_adapter * i2c_adap,struct i2c_msg * msgs,int num)584b285192aSMauro Carvalho Chehab static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
585b285192aSMauro Carvalho Chehab {
586b285192aSMauro Carvalho Chehab 	struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
587b285192aSMauro Carvalho Chehab 	struct ivtv *itv = to_ivtv(v4l2_dev);
588b285192aSMauro Carvalho Chehab 	int retval;
589b285192aSMauro Carvalho Chehab 	int i;
590b285192aSMauro Carvalho Chehab 
591b285192aSMauro Carvalho Chehab 	mutex_lock(&itv->i2c_bus_lock);
592b285192aSMauro Carvalho Chehab 	for (i = retval = 0; retval == 0 && i < num; i++) {
593b285192aSMauro Carvalho Chehab 		if (msgs[i].flags & I2C_M_RD)
594b285192aSMauro Carvalho Chehab 			retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len);
595b285192aSMauro Carvalho Chehab 		else {
596b285192aSMauro Carvalho Chehab 			/* if followed by a read, don't stop */
597b285192aSMauro Carvalho Chehab 			int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD);
598b285192aSMauro Carvalho Chehab 
599b285192aSMauro Carvalho Chehab 			retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop);
600b285192aSMauro Carvalho Chehab 		}
601b285192aSMauro Carvalho Chehab 	}
602b285192aSMauro Carvalho Chehab 	mutex_unlock(&itv->i2c_bus_lock);
603b285192aSMauro Carvalho Chehab 	return retval ? retval : num;
604b285192aSMauro Carvalho Chehab }
605b285192aSMauro Carvalho Chehab 
606b285192aSMauro Carvalho Chehab /* Kernel i2c capabilities */
ivtv_functionality(struct i2c_adapter * adap)607b285192aSMauro Carvalho Chehab static u32 ivtv_functionality(struct i2c_adapter *adap)
608b285192aSMauro Carvalho Chehab {
609b285192aSMauro Carvalho Chehab 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
610b285192aSMauro Carvalho Chehab }
611b285192aSMauro Carvalho Chehab 
61278f2c50bSJulia Lawall static const struct i2c_algorithm ivtv_algo = {
613b285192aSMauro Carvalho Chehab 	.master_xfer   = ivtv_xfer,
614b285192aSMauro Carvalho Chehab 	.functionality = ivtv_functionality,
615b285192aSMauro Carvalho Chehab };
616b285192aSMauro Carvalho Chehab 
617b285192aSMauro Carvalho Chehab /* template for our-bit banger */
618e5fffebeSBhumika Goyal static const struct i2c_adapter ivtv_i2c_adap_hw_template = {
619b285192aSMauro Carvalho Chehab 	.name = "ivtv i2c driver",
620b285192aSMauro Carvalho Chehab 	.algo = &ivtv_algo,
621b285192aSMauro Carvalho Chehab 	.algo_data = NULL,			/* filled from template */
622b285192aSMauro Carvalho Chehab 	.owner = THIS_MODULE,
623b285192aSMauro Carvalho Chehab };
624b285192aSMauro Carvalho Chehab 
ivtv_setscl_old(void * data,int state)625b285192aSMauro Carvalho Chehab static void ivtv_setscl_old(void *data, int state)
626b285192aSMauro Carvalho Chehab {
627b285192aSMauro Carvalho Chehab 	struct ivtv *itv = (struct ivtv *)data;
628b285192aSMauro Carvalho Chehab 
629b285192aSMauro Carvalho Chehab 	if (state)
630b285192aSMauro Carvalho Chehab 		itv->i2c_state |= 0x01;
631b285192aSMauro Carvalho Chehab 	else
632b285192aSMauro Carvalho Chehab 		itv->i2c_state &= ~0x01;
633b285192aSMauro Carvalho Chehab 
634b285192aSMauro Carvalho Chehab 	/* write them out */
635b285192aSMauro Carvalho Chehab 	/* write bits are inverted */
636b285192aSMauro Carvalho Chehab 	write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET);
637b285192aSMauro Carvalho Chehab }
638b285192aSMauro Carvalho Chehab 
ivtv_setsda_old(void * data,int state)639b285192aSMauro Carvalho Chehab static void ivtv_setsda_old(void *data, int state)
640b285192aSMauro Carvalho Chehab {
641b285192aSMauro Carvalho Chehab 	struct ivtv *itv = (struct ivtv *)data;
642b285192aSMauro Carvalho Chehab 
643b285192aSMauro Carvalho Chehab 	if (state)
644b285192aSMauro Carvalho Chehab 		itv->i2c_state |= 0x01;
645b285192aSMauro Carvalho Chehab 	else
646b285192aSMauro Carvalho Chehab 		itv->i2c_state &= ~0x01;
647b285192aSMauro Carvalho Chehab 
648b285192aSMauro Carvalho Chehab 	/* write them out */
649b285192aSMauro Carvalho Chehab 	/* write bits are inverted */
650b285192aSMauro Carvalho Chehab 	write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET);
651b285192aSMauro Carvalho Chehab }
652b285192aSMauro Carvalho Chehab 
ivtv_getscl_old(void * data)653b285192aSMauro Carvalho Chehab static int ivtv_getscl_old(void *data)
654b285192aSMauro Carvalho Chehab {
655b285192aSMauro Carvalho Chehab 	struct ivtv *itv = (struct ivtv *)data;
656b285192aSMauro Carvalho Chehab 
657b285192aSMauro Carvalho Chehab 	return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
658b285192aSMauro Carvalho Chehab }
659b285192aSMauro Carvalho Chehab 
ivtv_getsda_old(void * data)660b285192aSMauro Carvalho Chehab static int ivtv_getsda_old(void *data)
661b285192aSMauro Carvalho Chehab {
662b285192aSMauro Carvalho Chehab 	struct ivtv *itv = (struct ivtv *)data;
663b285192aSMauro Carvalho Chehab 
664b285192aSMauro Carvalho Chehab 	return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
665b285192aSMauro Carvalho Chehab }
666b285192aSMauro Carvalho Chehab 
667b285192aSMauro Carvalho Chehab /* template for i2c-bit-algo */
668e5fffebeSBhumika Goyal static const struct i2c_adapter ivtv_i2c_adap_template = {
669b285192aSMauro Carvalho Chehab 	.name = "ivtv i2c driver",
670b285192aSMauro Carvalho Chehab 	.algo = NULL,                   /* set by i2c-algo-bit */
671b285192aSMauro Carvalho Chehab 	.algo_data = NULL,              /* filled from template */
672b285192aSMauro Carvalho Chehab 	.owner = THIS_MODULE,
673b285192aSMauro Carvalho Chehab };
674b285192aSMauro Carvalho Chehab 
675b285192aSMauro Carvalho Chehab #define IVTV_ALGO_BIT_TIMEOUT	(2)	/* seconds */
676b285192aSMauro Carvalho Chehab 
677b285192aSMauro Carvalho Chehab static const struct i2c_algo_bit_data ivtv_i2c_algo_template = {
678b285192aSMauro Carvalho Chehab 	.setsda		= ivtv_setsda_old,
679b285192aSMauro Carvalho Chehab 	.setscl		= ivtv_setscl_old,
680b285192aSMauro Carvalho Chehab 	.getsda		= ivtv_getsda_old,
681b285192aSMauro Carvalho Chehab 	.getscl		= ivtv_getscl_old,
682b285192aSMauro Carvalho Chehab 	.udelay		= IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2,  /* microseconds */
683b285192aSMauro Carvalho Chehab 	.timeout	= IVTV_ALGO_BIT_TIMEOUT * HZ,         /* jiffies */
684b285192aSMauro Carvalho Chehab };
685b285192aSMauro Carvalho Chehab 
686b8e9b36dSBhumika Goyal static const struct i2c_client ivtv_i2c_client_template = {
687b285192aSMauro Carvalho Chehab 	.name = "ivtv internal",
688b285192aSMauro Carvalho Chehab };
689b285192aSMauro Carvalho Chehab 
690b285192aSMauro Carvalho Chehab /* init + register i2c adapter */
init_ivtv_i2c(struct ivtv * itv)691b285192aSMauro Carvalho Chehab int init_ivtv_i2c(struct ivtv *itv)
692b285192aSMauro Carvalho Chehab {
693b285192aSMauro Carvalho Chehab 	int retval;
694b285192aSMauro Carvalho Chehab 
695b285192aSMauro Carvalho Chehab 	IVTV_DEBUG_I2C("i2c init\n");
696b285192aSMauro Carvalho Chehab 
697b285192aSMauro Carvalho Chehab 	/* Sanity checks for the I2C hardware arrays. They must be the
698b285192aSMauro Carvalho Chehab 	 * same size.
699b285192aSMauro Carvalho Chehab 	 */
700b285192aSMauro Carvalho Chehab 	if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) {
701b285192aSMauro Carvalho Chehab 		IVTV_ERR("Mismatched I2C hardware arrays\n");
702b285192aSMauro Carvalho Chehab 		return -ENODEV;
703b285192aSMauro Carvalho Chehab 	}
704b285192aSMauro Carvalho Chehab 	if (itv->options.newi2c > 0) {
70501a5cbebSEzequiel Garcia 		itv->i2c_adap = ivtv_i2c_adap_hw_template;
706b285192aSMauro Carvalho Chehab 	} else {
70701a5cbebSEzequiel Garcia 		itv->i2c_adap = ivtv_i2c_adap_template;
70801a5cbebSEzequiel Garcia 		itv->i2c_algo = ivtv_i2c_algo_template;
709b285192aSMauro Carvalho Chehab 	}
710b285192aSMauro Carvalho Chehab 	itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2;
711b285192aSMauro Carvalho Chehab 	itv->i2c_algo.data = itv;
712b285192aSMauro Carvalho Chehab 	itv->i2c_adap.algo_data = &itv->i2c_algo;
713b285192aSMauro Carvalho Chehab 
714b285192aSMauro Carvalho Chehab 	sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
715b285192aSMauro Carvalho Chehab 		itv->instance);
716b285192aSMauro Carvalho Chehab 	i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
717b285192aSMauro Carvalho Chehab 
71801a5cbebSEzequiel Garcia 	itv->i2c_client = ivtv_i2c_client_template;
719b285192aSMauro Carvalho Chehab 	itv->i2c_client.adapter = &itv->i2c_adap;
720b285192aSMauro Carvalho Chehab 	itv->i2c_adap.dev.parent = &itv->pdev->dev;
721b285192aSMauro Carvalho Chehab 
722b285192aSMauro Carvalho Chehab 	IVTV_DEBUG_I2C("setting scl and sda to 1\n");
723b285192aSMauro Carvalho Chehab 	ivtv_setscl(itv, 1);
724b285192aSMauro Carvalho Chehab 	ivtv_setsda(itv, 1);
725b285192aSMauro Carvalho Chehab 
726b285192aSMauro Carvalho Chehab 	if (itv->options.newi2c > 0)
727b285192aSMauro Carvalho Chehab 		retval = i2c_add_adapter(&itv->i2c_adap);
728b285192aSMauro Carvalho Chehab 	else
729b285192aSMauro Carvalho Chehab 		retval = i2c_bit_add_bus(&itv->i2c_adap);
730b285192aSMauro Carvalho Chehab 
731b285192aSMauro Carvalho Chehab 	return retval;
732b285192aSMauro Carvalho Chehab }
733b285192aSMauro Carvalho Chehab 
exit_ivtv_i2c(struct ivtv * itv)734b285192aSMauro Carvalho Chehab void exit_ivtv_i2c(struct ivtv *itv)
735b285192aSMauro Carvalho Chehab {
736b285192aSMauro Carvalho Chehab 	IVTV_DEBUG_I2C("i2c exit\n");
737b285192aSMauro Carvalho Chehab 
738b285192aSMauro Carvalho Chehab 	i2c_del_adapter(&itv->i2c_adap);
739b285192aSMauro Carvalho Chehab }
740