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