11a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* 21a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil I2C functions 31a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com> 41a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl> 51a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 61a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is free software; you can redistribute it and/or modify 71a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil it under the terms of the GNU General Public License as published by 81a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil the Free Software Foundation; either version 2 of the License, or 91a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil (at your option) any later version. 101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This program is distributed in the hope that it will be useful, 121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil but WITHOUT ANY WARRANTY; without even the implied warranty of 131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil GNU General Public License for more details. 151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil You should have received a copy of the GNU General Public License 171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil along with this program; if not, write to the Free Software 181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */ 201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* 221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This file includes an i2c implementation that was reverse engineered 231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil from the Hauppauge windows driver. Older ivtv versions used i2c-algo-bit, 241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil which whilst fine under most circumstances, had trouble with the Zilog 251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil CPU on the PVR-150 which handles IR functions (occasional inability to 261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil communicate with the chip until it was reset) and also with the i2c 271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil bus being completely unreachable when multiple PVR cards were present. 281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil The implementation is very similar to i2c-algo-bit, but there are enough 301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil subtle differences that the two are hard to merge. The general strategy 311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil employed by i2c-algo-bit is to use udelay() to implement the timing 321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil when putting out bits on the scl/sda lines. The general strategy taken 331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil here is to poll the lines for state changes (see ivtv_waitscl and 341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_waitsda). In addition there are small delays at various locations 351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil which poll the SCL line 5 times (ivtv_scldelay). I would guess that 361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil since this is memory mapped I/O that the length of those delays is tied 371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to the PCI bus clock. There is some extra code to do with recovery 381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil and retries. Since it is not known what causes the actual i2c problems 391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil in the first place, the only goal if one was to attempt to use 401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil i2c-algo-bit would be to try to make it follow the same code path. 411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil This would be a lot of work, and I'm also not convinced that it would 421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil provide a generic benefit to i2c-algo-bit. Therefore consider this 431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil an engineering solution -- not pretty, but it works. 441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil Some more general comments about what we are doing: 461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil The i2c bus is a 2 wire serial bus, with clock (SCL) and data (SDA) 481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil lines. To communicate on the bus (as a master, we don't act as a slave), 491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil we first initiate a start condition (ivtv_start). We then write the 501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil address of the device that we want to communicate with, along with a flag 511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil that indicates whether this is a read or a write. The slave then issues 521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil an ACK signal (ivtv_ack), which tells us that it is ready for reading / 531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil writing. We then proceed with reading or writing (ivtv_read/ivtv_write), 541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil and finally issue a stop condition (ivtv_stop) to make the bus available 551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil to other masters. 561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil There is an additional form of transaction where a write may be 581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil immediately followed by a read. In this case, there is no intervening 591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil stop condition. (Only the msp3400 chip uses this method of data transfer). 601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */ 611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-driver.h" 631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-cards.h" 641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#include "ivtv-gpio.h" 6583df8e7b0d7b319f9ce9773eaf4b1da324ae17d7Hans Verkuil#include "ivtv-i2c.h" 6672c851b00f6c86353c54fdd9f1ef88d82e8df6c5Hans Verkuil#include <media/cx25840.h> 671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* i2c implementation for cx23415/6 chip, ivtv project. 691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil * Author: Kevin Thayer (nufan_wfk at yahoo.com) 701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil */ 711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* i2c stuff */ 721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_REG_I2C_SETSCL_OFFSET 0x7000 731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_REG_I2C_SETSDA_OFFSET 0x7004 741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_REG_I2C_GETSCL_OFFSET 0x7008 751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_REG_I2C_GETSDA_OFFSET 0x700c 761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_CS53L32A_I2C_ADDR 0x11 78e2a1774d9c8b866db65853fd1a17e5f472dd5cf2Hans Verkuil#define IVTV_M52790_I2C_ADDR 0x48 791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_CX25840_I2C_ADDR 0x44 801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_SAA7115_I2C_ADDR 0x21 811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_SAA7127_I2C_ADDR 0x44 821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_SAA717x_I2C_ADDR 0x21 831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_MSP3400_I2C_ADDR 0x40 841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_HAUPPAUGE_I2C_ADDR 0x50 851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_WM8739_I2C_ADDR 0x1a 861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_WM8775_I2C_ADDR 0x1b 871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_TEA5767_I2C_ADDR 0x60 881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_UPD64031A_I2C_ADDR 0x12 891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil#define IVTV_UPD64083_I2C_ADDR 0x5c 90d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil#define IVTV_VP27SMPX_I2C_ADDR 0x5b 91d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil#define IVTV_M52790_I2C_ADDR 0x48 92ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40 937ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a 947ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 957ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 967ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 97e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab#define IVTV_ADAPTEC_IR_ADDR 0x6b 981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* This array should match the IVTV_HW_ defines */ 100d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuilstatic const u8 hw_addrs[] = { 101d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_CX25840_I2C_ADDR, 102d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_SAA7115_I2C_ADDR, 103d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_SAA7127_I2C_ADDR, 104d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_MSP3400_I2C_ADDR, 105d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil 0, 106d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_WM8775_I2C_ADDR, 107d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_CS53L32A_I2C_ADDR, 108d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil 0, 109d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_SAA7115_I2C_ADDR, 110d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_UPD64031A_I2C_ADDR, 111d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_UPD64083_I2C_ADDR, 112d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_SAA717x_I2C_ADDR, 113d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_WM8739_I2C_ADDR, 114d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_VP27SMPX_I2C_ADDR, 115d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_M52790_I2C_ADDR, 116ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 0, /* IVTV_HW_GPIO dummy driver ID */ 1177ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */ 1187ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ 1197ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */ 1207ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */ 1217ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */ 122e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */ 123d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil}; 124d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil 125d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil/* This array should match the IVTV_HW_ defines */ 126af294867a52bf718df835a688e8c786d550bee26Jean Delvarestatic const char * const hw_devicenames[] = { 127d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil "cx25840", 1281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "saa7115", 1295daed07401ed27bb2684e803f3f01e3a424ea282Jean Delvare "saa7127_auto", /* saa7127 or saa7129 */ 1301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "msp3400", 1311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "tuner", 1321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "wm8775", 1331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "cs53l32a", 1341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "tveeprom", 135af294867a52bf718df835a688e8c786d550bee26Jean Delvare "saa7114", 1361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "upd64031a", 1371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "upd64083", 1381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "saa717x", 1391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "wm8739", 140ac247433fe205acf460f05de64a30ee71ea307f2Hans Verkuil "vp27smpx", 141e2a1774d9c8b866db65853fd1a17e5f472dd5cf2Hans Verkuil "m52790", 1421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil "gpio", 1437ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls "ir_video", /* IVTV_HW_I2C_IR_RX_AVER */ 1447ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */ 1457ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls "ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */ 1467ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */ 1477ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */ 148e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab "ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */ 1491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 1501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 151e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehabstatic int get_key_adaptec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 152e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab{ 153e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab unsigned char keybuf[4]; 154e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 155e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab keybuf[0] = 0x00; 156e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab i2c_master_send(ir->c, keybuf, 1); 157e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab /* poll IR chip */ 158e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab if (i2c_master_recv(ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { 159e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab return 0; 160e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab } 161e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 162e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab /* key pressed ? */ 163e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab if (keybuf[2] == 0xff) 164e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab return 0; 165e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 166e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab /* remove repeat bit */ 167e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab keybuf[2] &= 0x7f; 168e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab keybuf[3] |= 0x80; 169e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 1709804ed9e840c461f88b290dea43173e3eed37102Mauro Carvalho Chehab *ir_key = keybuf[3] | keybuf[2] << 8 | keybuf[1] << 16 |keybuf[0] << 24; 1719804ed9e840c461f88b290dea43173e3eed37102Mauro Carvalho Chehab *ir_raw = *ir_key; 172e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 173e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab return 1; 174e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab} 175e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab 176ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Wallsstatic int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr) 177ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls{ 178ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls struct i2c_board_info info; 179ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls struct i2c_adapter *adap = &itv->i2c_adap; 180ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data; 181ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; 182ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 1837ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls /* Only allow one IR transmitter to be registered per board */ 1847ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls if (hw & IVTV_HW_IR_TX_ANY) { 1857ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls if (itv->hw_flags & IVTV_HW_IR_TX_ANY) 1867ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls return -1; 1877ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls memset(&info, 0, sizeof(struct i2c_board_info)); 1887ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls strlcpy(info.type, type, I2C_NAME_SIZE); 1899a94241afcc9a481691a9c29b7460217925b59b8Jean Delvare return i2c_new_probed_device(adap, &info, addr_list, NULL) 1909a94241afcc9a481691a9c29b7460217925b59b8Jean Delvare == NULL ? -1 : 0; 1917ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls } 1927ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls 1937ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls /* Only allow one IR receiver to be registered per board */ 1947ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls if (itv->hw_flags & IVTV_HW_IR_RX_ANY) 1957ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls return -1; 1967ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls 197ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls /* Our default information for ir-kbd-i2c.c to use */ 198ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls switch (hw) { 199ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls case IVTV_HW_I2C_IR_RX_AVER: 20002858eedcb78a664215b918d98cdb753ce432ce6Mauro Carvalho Chehab init_data->ir_codes = RC_MAP_AVERMEDIA_CARDBUS; 201ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls init_data->internal_get_key_func = 202ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls IR_KBD_GET_KEY_AVERMEDIA_CARDBUS; 20352b661449aecc47e652a164c0d8078b31e10aca0Mauro Carvalho Chehab init_data->type = RC_TYPE_OTHER; 204ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls init_data->name = "AVerMedia AVerTV card"; 205ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls break; 2067ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls case IVTV_HW_I2C_IR_RX_HAUP_EXT: 2077ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls case IVTV_HW_I2C_IR_RX_HAUP_INT: 208206241069ecfa52c3b8873f8d7e31d434d2fcae1Mauro Carvalho Chehab init_data->ir_codes = RC_MAP_HAUPPAUGE; 2097ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 21052b661449aecc47e652a164c0d8078b31e10aca0Mauro Carvalho Chehab init_data->type = RC_TYPE_RC5; 2117ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls init_data->name = itv->card_name; 2127ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls break; 2137ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls case IVTV_HW_Z8F0811_IR_RX_HAUP: 2147ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls /* Default to grey remote */ 215af86ce79f020a31e4a30661e41471d31face9985Mauro Carvalho Chehab init_data->ir_codes = RC_MAP_HAUPPAUGE; 2167ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 21752b661449aecc47e652a164c0d8078b31e10aca0Mauro Carvalho Chehab init_data->type = RC_TYPE_RC5; 2187ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls init_data->name = itv->card_name; 2197ce5c41db3672c8b4419b16d9b3ac1ccf11a1445Andy Walls break; 220e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab case IVTV_HW_I2C_IR_RX_ADAPTEC: 221e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab init_data->get_key = get_key_adaptec; 222e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab init_data->name = itv->card_name; 223e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab /* FIXME: The protocol and RC_MAP needs to be corrected */ 224e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab init_data->ir_codes = RC_MAP_EMPTY; 225e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab init_data->type = RC_TYPE_UNKNOWN; 226e1e2c57565635310209566a31a300e593f74cc22Mauro Carvalho Chehab break; 227ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls } 228ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 229ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls memset(&info, 0, sizeof(struct i2c_board_info)); 230ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls info.platform_data = init_data; 231ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls strlcpy(info.type, type, I2C_NAME_SIZE); 232ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 2339a94241afcc9a481691a9c29b7460217925b59b8Jean Delvare return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? 2349a94241afcc9a481691a9c29b7460217925b59b8Jean Delvare -1 : 0; 235ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls} 236ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 237bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls/* Instantiate the IR receiver device using probing -- undesirable */ 238bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Wallsstruct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv) 239bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls{ 240bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls struct i2c_board_info info; 241bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls /* 242bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * The external IR receiver is at i2c address 0x34. 243bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * The internal IR receiver is at i2c address 0x30. 244bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * 245bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * In theory, both can be fitted, and Hauppauge suggests an external 246bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * overrides an internal. That's why we probe 0x1a (~0x34) first. CB 247bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * 248bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * Some of these addresses we probe may collide with other i2c address 249bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * allocations, so this function must be called after all other i2c 250bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls * devices we care about are registered. 251bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls */ 252bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls const unsigned short addr_list[] = { 253bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls 0x1a, /* Hauppauge IR external - collides with WM8739 */ 254bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls 0x18, /* Hauppauge IR internal */ 255bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls I2C_CLIENT_END 256bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls }; 257bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls 258bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls memset(&info, 0, sizeof(struct i2c_board_info)); 259bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 2609a94241afcc9a481691a9c29b7460217925b59b8Jean Delvare return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL); 261bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls} 262bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls 263d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuilint ivtv_i2c_register(struct ivtv *itv, unsigned idx) 2641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 26567ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil struct v4l2_subdev *sd; 26667ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil struct i2c_adapter *adap = &itv->i2c_adap; 26767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil const char *type = hw_devicenames[idx]; 26867ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil u32 hw = 1 << idx; 2691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 27067ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (idx >= ARRAY_SIZE(hw_addrs)) 271d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil return -1; 27267ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (hw == IVTV_HW_TUNER) { 27367ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil /* special tuner handling */ 2749a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, 2759a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart itv->card_i2c->radio); 27667ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (sd) 27767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil sd->grp_id = 1 << idx; 2789a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, 2799a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart itv->card_i2c->demod); 28067ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (sd) 28167ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil sd->grp_id = 1 << idx; 2829a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, 0, 2839a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart itv->card_i2c->tv); 28467ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (sd) 28567ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil sd->grp_id = 1 << idx; 28667ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil return sd ? 0 : -1; 2871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 288ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 289ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls if (hw & IVTV_HW_IR_ANY) 290ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls return ivtv_i2c_new_ir(itv, hw, type, hw_addrs[idx]); 291ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 292ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls /* Is it not an I2C device or one we do not wish to register? */ 29367ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (!hw_addrs[idx]) 29467ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil return -1; 295ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls 296ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls /* It's an I2C device other than an analog tuner or IR chip */ 29767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { 29853dacb15705901e14b03dcba27e40364fedd9d09Hans Verkuil sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 2999a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart adap, type, 0, I2C_ADDRS(hw_addrs[idx])); 30072c851b00f6c86353c54fdd9f1ef88d82e8df6c5Hans Verkuil } else if (hw == IVTV_HW_CX25840) { 30172c851b00f6c86353c54fdd9f1ef88d82e8df6c5Hans Verkuil struct cx25840_platform_data pdata; 3023c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil struct i2c_board_info cx25840_info = { 3033c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil .type = "cx25840", 3043c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil .addr = hw_addrs[idx], 3053c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil .platform_data = &pdata, 3063c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil }; 30772c851b00f6c86353c54fdd9f1ef88d82e8df6c5Hans Verkuil 30872c851b00f6c86353c54fdd9f1ef88d82e8df6c5Hans Verkuil pdata.pvr150_workaround = itv->pvr150_workaround; 3093c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap, 3103c7c9370fb645f4713e0fbbe69425d8db9b47a13Hans Verkuil &cx25840_info, NULL); 31167ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil } else { 312e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 3139a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart adap, type, hw_addrs[idx], NULL); 314d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil } 31567ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (sd) 31667ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil sd->grp_id = 1 << idx; 31767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil return sd ? 0 : -1; 3181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 32067ec09fdf5e05d4670b617256c696348b5df080bHans Verkuilstruct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw) 3211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 32267ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil struct v4l2_subdev *result = NULL; 32367ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil struct v4l2_subdev *sd; 3241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3258ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil spin_lock(&itv->v4l2_dev.lock); 3268ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) { 32767ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil if (sd->grp_id == hw) { 32867ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil result = sd; 3291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil break; 3301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3328ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil spin_unlock(&itv->v4l2_dev.lock); 33367ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil return result; 3341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Set the serial clock line to the desired state */ 3371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setscl(struct ivtv *itv, int state) 3381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write them out */ 3401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write bits are inverted */ 3411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET); 3421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Set the serial data line to the desired state */ 3451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setsda(struct ivtv *itv, int state) 3461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write them out */ 3481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write bits are inverted */ 3491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET); 3501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Read the serial clock line */ 3531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_getscl(struct ivtv *itv) 3541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1; 3561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Read the serial data line */ 3591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_getsda(struct ivtv *itv) 3601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1; 3621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Implement a short delay by polling the serial clock line */ 3651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_scldelay(struct ivtv *itv) 3661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 3681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 5; ++i) 3701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_getscl(itv); 3711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Wait for the serial clock line to become set to a specific value */ 3741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_waitscl(struct ivtv *itv, int val) 3751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 3771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 3791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 1000; ++i) { 3801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_getscl(itv) == val) 3811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 1; 3821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 3841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Wait for the serial data line to become set to a specific value */ 3871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_waitsda(struct ivtv *itv, int val) 3881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 3891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 3901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 3921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 1000; ++i) { 3931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_getsda(itv) == val) 3941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 1; 3951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 3961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 3971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 3981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 3991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Wait for the slave to issue an ACK */ 4001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_ack(struct ivtv *itv) 4011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int ret = 0; 4031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_getscl(itv) == 1) { 40511d28766deedc8bcadc87db8a65775a41c15789aHans Verkuil IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n"); 4061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 0)) { 4081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n"); 4091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 4131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 4151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitsda(itv, 0)) { 4161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Slave did not ack\n"); 4171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = -EREMOTEIO; 4181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 0)) { 4211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Failed to set SCL low after ACK\n"); 4221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = -EREMOTEIO; 4231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ret; 4251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 4261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Write a single byte to the i2c bus and wait for the slave to ACK */ 4281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_sendbyte(struct ivtv *itv, unsigned char byte) 4291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i, bit; 4311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 43211d28766deedc8bcadc87db8a65775a41c15789aHans Verkuil IVTV_DEBUG_HI_I2C("write %x\n",byte); 4331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 8; ++i, byte<<=1) { 4341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 0)) { 4361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Error setting SCL low\n"); 4371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil bit = (byte>>7)&1; 4401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, bit); 4411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitsda(itv, bit)) { 4421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Error setting SDA\n"); 4431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 4461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 1)) { 4471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Slave not ready for bit\n"); 4481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 0)) { 4531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Error setting SCL low\n"); 4541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ivtv_ack(itv); 4571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 4581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Read a byte from the i2c bus and send a NACK if applicable (i.e. for the 4601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil final byte) */ 4611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_readbyte(struct ivtv *itv, unsigned char *byte, int nack) 4621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 4641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil *byte = 0; 4661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 4681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 8; ++i) { 4701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 4731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 1)) { 4741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("Error setting SCL high\n"); 4751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 4761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil *byte = ((*byte)<<1)|ivtv_getsda(itv); 4781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 4791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, nack); 4821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 4841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 4851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 4861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 48711d28766deedc8bcadc87db8a65775a41c15789aHans Verkuil IVTV_DEBUG_HI_I2C("read %x\n",*byte); 4881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 4891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 4901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Issue a start condition on the i2c bus to alert slaves to prepare for 4921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil an address write */ 4931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_start(struct ivtv *itv) 4941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 4951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int sda; 4961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 4971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sda = ivtv_getsda(itv); 4981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (sda != 1) { 49911d28766deedc8bcadc87db8a65775a41c15789aHans Verkuil IVTV_DEBUG_HI_I2C("SDA was low at start\n"); 5001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 5011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitsda(itv, 1)) { 5021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("SDA stuck low\n"); 5031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 5041a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_getscl(itv) != 1) { 5071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 5081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 1)) { 5091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("SCL stuck low at start\n"); 5101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 5111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 0); 5141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 5151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 5161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Issue a stop condition on the i2c bus to release it */ 5191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_stop(struct ivtv *itv) 5201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 5211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 5221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ivtv_getscl(itv) != 0) { 52411d28766deedc8bcadc87db8a65775a41c15789aHans Verkuil IVTV_DEBUG_HI_I2C("SCL not low when stopping\n"); 5251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 5261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 0)) { 5271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("SCL could not be set low\n"); 5281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 0); 5311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 5321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 5331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitscl(itv, 1)) { 5341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("SCL could not be set high\n"); 5351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 5361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 5381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 5391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (!ivtv_waitsda(itv, 1)) { 5401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("resetting I2C\n"); 5411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; i < 16; ++i) { 5421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 0); 5431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 5441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 5451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_scldelay(itv); 5461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 5471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_waitsda(itv, 1); 5491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return -EREMOTEIO; 5501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return 0; 5521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Write a message to the given i2c slave. do_stop may be 0 to prevent 5551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil issuing the i2c stop condition (when following with a read) */ 5561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_write(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len, int do_stop) 5571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 5581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int retry, ret = -EREMOTEIO; 5591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 i; 5601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (retry = 0; ret != 0 && retry < 8; ++retry) { 5621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_start(itv); 5631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ret == 0) { 5651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_sendbyte(itv, addr<<1); 5661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; ret == 0 && i < len; ++i) 5671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_sendbyte(itv, data[i]); 5681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ret != 0 || do_stop) { 5701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop(itv); 5711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ret) 5741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("i2c write to %x failed\n", addr); 5751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ret; 5761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Read data from the given i2c slave. A stop condition is always issued. */ 5791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data, u32 len) 5801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 5811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int retry, ret = -EREMOTEIO; 5821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil u32 i; 5831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (retry = 0; ret != 0 && retry < 8; ++retry) { 5851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_start(itv); 5861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ret == 0) 5871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_sendbyte(itv, (addr << 1) | 1); 5881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = 0; ret == 0 && i < len; ++i) { 5891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ret = ivtv_readbyte(itv, &data[i], i == len - 1); 5901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_stop(itv); 5921a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 5931a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (ret) 5941a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("i2c read from %x failed\n", addr); 5951a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return ret; 5961a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 5971a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 5981a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Kernel i2c transfer implementation. Takes a number of messages to be read 5991a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil or written. If a read follows a write, this will occur without an 6001a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil intervening stop condition */ 6011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 6021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6038ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap); 6048ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil struct ivtv *itv = to_ivtv(v4l2_dev); 6051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int retval; 6061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int i; 6071a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6081a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil mutex_lock(&itv->i2c_bus_lock); 6091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil for (i = retval = 0; retval == 0 && i < num; i++) { 6101a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (msgs[i].flags & I2C_M_RD) 6111a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil retval = ivtv_read(itv, msgs[i].addr, msgs[i].buf, msgs[i].len); 6121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else { 6131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* if followed by a read, don't stop */ 6141a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil int stop = !(i + 1 < num && msgs[i + 1].flags == I2C_M_RD); 6151a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6161a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil retval = ivtv_write(itv, msgs[i].addr, msgs[i].buf, msgs[i].len, stop); 6171a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6181a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 6191a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil mutex_unlock(&itv->i2c_bus_lock); 6201a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return retval ? retval : num; 6211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* Kernel i2c capabilities */ 6241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic u32 ivtv_functionality(struct i2c_adapter *adap) 6251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 6271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct i2c_algorithm ivtv_algo = { 6301a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .master_xfer = ivtv_xfer, 6311a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .functionality = ivtv_functionality, 6321a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 6331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* template for our-bit banger */ 6351a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct i2c_adapter ivtv_i2c_adap_hw_template = { 6361a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .name = "ivtv i2c driver", 6371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .algo = &ivtv_algo, 6381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .algo_data = NULL, /* filled from template */ 6391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .owner = THIS_MODULE, 6401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 6411a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setscl_old(void *data, int state) 6431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = (struct ivtv *)data; 6451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (state) 6471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->i2c_state |= 0x01; 6481a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else 6491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->i2c_state &= ~0x01; 6501a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6511a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write them out */ 6521a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write bits are inverted */ 6531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSCL_OFFSET); 6541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6551a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic void ivtv_setsda_old(void *data, int state) 6571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = (struct ivtv *)data; 6591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (state) 6611a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->i2c_state |= 0x01; 6621a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else 6631a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->i2c_state &= ~0x01; 6641a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6651a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write them out */ 6661a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil /* write bits are inverted */ 6671a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil write_reg(~itv->i2c_state, IVTV_REG_I2C_SETSDA_OFFSET); 6681a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6691a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6701a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_getscl_old(void *data) 6711a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6721a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = (struct ivtv *)data; 6731a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6741a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1; 6751a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6761a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6771a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic int ivtv_getsda_old(void *data) 6781a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 6791a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil struct ivtv *itv = (struct ivtv *)data; 6801a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6811a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1; 6821a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 6831a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 6841a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil/* template for i2c-bit-algo */ 6851a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct i2c_adapter ivtv_i2c_adap_template = { 6861a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .name = "ivtv i2c driver", 6871a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .algo = NULL, /* set by i2c-algo-bit */ 6881a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .algo_data = NULL, /* filled from template */ 6891a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil .owner = THIS_MODULE, 6901a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 6911a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 692f412d36a8c9f8e40e057b71e80d534ac388e903eAndy Walls#define IVTV_ALGO_BIT_TIMEOUT (2) /* seconds */ 693f412d36a8c9f8e40e057b71e80d534ac388e903eAndy Walls 694aeb292d1342c649ac0b35ae9205b761fd14adb57Jean Delvarestatic const struct i2c_algo_bit_data ivtv_i2c_algo_template = { 695aeb292d1342c649ac0b35ae9205b761fd14adb57Jean Delvare .setsda = ivtv_setsda_old, 696aeb292d1342c649ac0b35ae9205b761fd14adb57Jean Delvare .setscl = ivtv_setscl_old, 697aeb292d1342c649ac0b35ae9205b761fd14adb57Jean Delvare .getsda = ivtv_getsda_old, 698aeb292d1342c649ac0b35ae9205b761fd14adb57Jean Delvare .getscl = ivtv_getscl_old, 699f412d36a8c9f8e40e057b71e80d534ac388e903eAndy Walls .udelay = IVTV_DEFAULT_I2C_CLOCK_PERIOD / 2, /* microseconds */ 700f412d36a8c9f8e40e057b71e80d534ac388e903eAndy Walls .timeout = IVTV_ALGO_BIT_TIMEOUT * HZ, /* jiffies */ 7011a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 7021a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7031a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuilstatic struct i2c_client ivtv_i2c_client_template = { 704a415783bbb9fba7be2eeaeb5e3e08262bd3d64a1Andrew Morton .name = "ivtv internal", 7051a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil}; 7061a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 707bfbde8ee56d4a19e2d36a5a24b6dbfd298298bf1Andy Walls/* init + register i2c adapter */ 708056827a49ce65a8d10197d35468500b501d1eec1Adrian Bunkint init_ivtv_i2c(struct ivtv *itv) 7091a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 710c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare int retval; 711c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare 7121a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("i2c init\n"); 7131a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 714d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil /* Sanity checks for the I2C hardware arrays. They must be the 715ad2fe2d48812029b0b674594f297d0723f7c6e8fAndy Walls * same size. 716d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil */ 71784d0d4f0674c55d0625bd1b6eb91dba4ef3948f9Laurent Pinchart if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs)) { 718d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil IVTV_ERR("Mismatched I2C hardware arrays\n"); 719d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil return -ENODEV; 720d9009201207c4bdce9b95a0bd903b3f087e8eda1Hans Verkuil } 7211a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (itv->options.newi2c > 0) { 7221a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil memcpy(&itv->i2c_adap, &ivtv_i2c_adap_hw_template, 7231a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sizeof(struct i2c_adapter)); 7241a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } else { 7251a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil memcpy(&itv->i2c_adap, &ivtv_i2c_adap_template, 7261a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sizeof(struct i2c_adapter)); 7271a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template, 7281a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sizeof(struct i2c_algo_bit_data)); 7291a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil } 730f412d36a8c9f8e40e057b71e80d534ac388e903eAndy Walls itv->i2c_algo.udelay = itv->options.i2c_clock_period / 2; 7310e614cd1a5a09b36a3b6d0fff8a08a97800d3cceHans Verkuil itv->i2c_algo.data = itv; 7320e614cd1a5a09b36a3b6d0fff8a08a97800d3cceHans Verkuil itv->i2c_adap.algo_data = &itv->i2c_algo; 7331a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7341a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", 73567ec09fdf5e05d4670b617256c696348b5df080bHans Verkuil itv->instance); 7368ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev); 7371a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7381a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil memcpy(&itv->i2c_client, &ivtv_i2c_client_template, 7391a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil sizeof(struct i2c_client)); 7401a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil itv->i2c_client.adapter = &itv->i2c_adap; 7418ac05ae3192ce8a71fc84e4a88772cce0c09173cHans Verkuil itv->i2c_adap.dev.parent = &itv->pdev->dev; 7421a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7431a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("setting scl and sda to 1\n"); 7441a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setscl(itv, 1); 7451a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil ivtv_setsda(itv, 1); 7461a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7471a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil if (itv->options.newi2c > 0) 748c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare retval = i2c_add_adapter(&itv->i2c_adap); 7491a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil else 750c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare retval = i2c_bit_add_bus(&itv->i2c_adap); 751c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare 752c668f32dca105d876e51862a003a302fa61e4ae4Jean Delvare return retval; 7531a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 7541a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 755bb374b7b938f73666c403b201b3dd48ec9fe118aDavid Millervoid exit_ivtv_i2c(struct ivtv *itv) 7561a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil{ 7571a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil IVTV_DEBUG_I2C("i2c exit\n"); 7581a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil 7591a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil i2c_del_adapter(&itv->i2c_adap); 7601a0adaf37c30e89e44d1470ef604a930999a5826Hans Verkuil} 761