10c0d06caSMauro Carvalho Chehab /* 20c0d06caSMauro Carvalho Chehab em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices 30c0d06caSMauro Carvalho Chehab 40c0d06caSMauro Carvalho Chehab Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> 50c0d06caSMauro Carvalho Chehab Markus Rechberger <mrechberger@gmail.com> 60c0d06caSMauro Carvalho Chehab Mauro Carvalho Chehab <mchehab@infradead.org> 70c0d06caSMauro Carvalho Chehab Sascha Sommer <saschasommer@freenet.de> 8a3ea4bf9SFrank Schaefer Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com> 90c0d06caSMauro Carvalho Chehab 100c0d06caSMauro Carvalho Chehab This program is free software; you can redistribute it and/or modify 110c0d06caSMauro Carvalho Chehab it under the terms of the GNU General Public License as published by 120c0d06caSMauro Carvalho Chehab the Free Software Foundation; either version 2 of the License, or 130c0d06caSMauro Carvalho Chehab (at your option) any later version. 140c0d06caSMauro Carvalho Chehab 150c0d06caSMauro Carvalho Chehab This program is distributed in the hope that it will be useful, 160c0d06caSMauro Carvalho Chehab but WITHOUT ANY WARRANTY; without even the implied warranty of 170c0d06caSMauro Carvalho Chehab MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 180c0d06caSMauro Carvalho Chehab GNU General Public License for more details. 190c0d06caSMauro Carvalho Chehab 200c0d06caSMauro Carvalho Chehab You should have received a copy of the GNU General Public License 210c0d06caSMauro Carvalho Chehab along with this program; if not, write to the Free Software 220c0d06caSMauro Carvalho Chehab Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 230c0d06caSMauro Carvalho Chehab */ 240c0d06caSMauro Carvalho Chehab 250c0d06caSMauro Carvalho Chehab #include <linux/module.h> 260c0d06caSMauro Carvalho Chehab #include <linux/kernel.h> 270c0d06caSMauro Carvalho Chehab #include <linux/usb.h> 280c0d06caSMauro Carvalho Chehab #include <linux/i2c.h> 294b83626aSMauro Carvalho Chehab #include <linux/jiffies.h> 300c0d06caSMauro Carvalho Chehab 310c0d06caSMauro Carvalho Chehab #include "em28xx.h" 320c0d06caSMauro Carvalho Chehab #include "tuner-xc2028.h" 330c0d06caSMauro Carvalho Chehab #include <media/v4l2-common.h> 340c0d06caSMauro Carvalho Chehab #include <media/tuner.h> 350c0d06caSMauro Carvalho Chehab 360c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 370c0d06caSMauro Carvalho Chehab 380c0d06caSMauro Carvalho Chehab static unsigned int i2c_scan; 390c0d06caSMauro Carvalho Chehab module_param(i2c_scan, int, 0444); 400c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 410c0d06caSMauro Carvalho Chehab 420c0d06caSMauro Carvalho Chehab static unsigned int i2c_debug; 430c0d06caSMauro Carvalho Chehab module_param(i2c_debug, int, 0644); 4450f0a9dfSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)"); 450c0d06caSMauro Carvalho Chehab 460c0d06caSMauro Carvalho Chehab /* 47f5ae371aSFrank Schaefer * em2800_i2c_send_bytes() 48f5ae371aSFrank Schaefer * send up to 4 bytes to the em2800 i2c device 490c0d06caSMauro Carvalho Chehab */ 50f5ae371aSFrank Schaefer static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 510c0d06caSMauro Carvalho Chehab { 52d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 530c0d06caSMauro Carvalho Chehab int ret; 54a6bad040SFrank Schaefer u8 b2[6]; 55f5ae371aSFrank Schaefer 56f5ae371aSFrank Schaefer if (len < 1 || len > 4) 57f5ae371aSFrank Schaefer return -EOPNOTSUPP; 58f5ae371aSFrank Schaefer 590c0d06caSMauro Carvalho Chehab BUG_ON(len < 1 || len > 4); 600c0d06caSMauro Carvalho Chehab b2[5] = 0x80 + len - 1; 610c0d06caSMauro Carvalho Chehab b2[4] = addr; 620c0d06caSMauro Carvalho Chehab b2[3] = buf[0]; 630c0d06caSMauro Carvalho Chehab if (len > 1) 640c0d06caSMauro Carvalho Chehab b2[2] = buf[1]; 650c0d06caSMauro Carvalho Chehab if (len > 2) 660c0d06caSMauro Carvalho Chehab b2[1] = buf[2]; 670c0d06caSMauro Carvalho Chehab if (len > 3) 680c0d06caSMauro Carvalho Chehab b2[0] = buf[3]; 690c0d06caSMauro Carvalho Chehab 702fcc82d8SFrank Schaefer /* trigger write */ 710c0d06caSMauro Carvalho Chehab ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); 720c0d06caSMauro Carvalho Chehab if (ret != 2 + len) { 73d230d5adSFrank Schaefer em28xx_warn("failed to trigger write to i2c address 0x%x (error=%i)\n", 74d230d5adSFrank Schaefer addr, ret); 7545f04e82SFrank Schaefer return (ret < 0) ? ret : -EIO; 760c0d06caSMauro Carvalho Chehab } 772fcc82d8SFrank Schaefer /* wait for completion */ 784b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 790c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg(dev, 0x05); 804b83626aSMauro Carvalho Chehab if (ret == 0x80 + len - 1) 810c0d06caSMauro Carvalho Chehab return len; 824b83626aSMauro Carvalho Chehab if (ret == 0x94 + len - 1) { 83d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 848ae8cd6cSFrank Schaefer em28xx_warn("R05 returned 0x%02x: I2C ACK error\n", 85d845fb3aSMauro Carvalho Chehab ret); 86e63b009dSMauro Carvalho Chehab return -ENXIO; 874b83626aSMauro Carvalho Chehab } 884b83626aSMauro Carvalho Chehab if (ret < 0) { 89d230d5adSFrank Schaefer em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 90d230d5adSFrank Schaefer ret); 9145f04e82SFrank Schaefer return ret; 9245f04e82SFrank Schaefer } 930c0d06caSMauro Carvalho Chehab msleep(5); 940c0d06caSMauro Carvalho Chehab } 9550f0a9dfSMauro Carvalho Chehab if (i2c_debug) 9645f04e82SFrank Schaefer em28xx_warn("write to i2c device at 0x%x timed out\n", addr); 97e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 980c0d06caSMauro Carvalho Chehab } 990c0d06caSMauro Carvalho Chehab 1000c0d06caSMauro Carvalho Chehab /* 1010c0d06caSMauro Carvalho Chehab * em2800_i2c_recv_bytes() 1022fcc82d8SFrank Schaefer * read up to 4 bytes from the em2800 i2c device 1030c0d06caSMauro Carvalho Chehab */ 104a6bad040SFrank Schaefer static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 1050c0d06caSMauro Carvalho Chehab { 106d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 1072fcc82d8SFrank Schaefer u8 buf2[4]; 1080c0d06caSMauro Carvalho Chehab int ret; 1092fcc82d8SFrank Schaefer int i; 110f5ae371aSFrank Schaefer 111f5ae371aSFrank Schaefer if (len < 1 || len > 4) 112f5ae371aSFrank Schaefer return -EOPNOTSUPP; 113f5ae371aSFrank Schaefer 1142fcc82d8SFrank Schaefer /* trigger read */ 1152fcc82d8SFrank Schaefer buf2[1] = 0x84 + len - 1; 1162fcc82d8SFrank Schaefer buf2[0] = addr; 1172fcc82d8SFrank Schaefer ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); 1182fcc82d8SFrank Schaefer if (ret != 2) { 119d230d5adSFrank Schaefer em28xx_warn("failed to trigger read from i2c address 0x%x (error=%i)\n", 120d230d5adSFrank Schaefer addr, ret); 1212fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1222fcc82d8SFrank Schaefer } 1232fcc82d8SFrank Schaefer 1242fcc82d8SFrank Schaefer /* wait for completion */ 1254b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 1262fcc82d8SFrank Schaefer ret = dev->em28xx_read_reg(dev, 0x05); 1274b83626aSMauro Carvalho Chehab if (ret == 0x84 + len - 1) 1282fcc82d8SFrank Schaefer break; 1294b83626aSMauro Carvalho Chehab if (ret == 0x94 + len - 1) { 130d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 1318ae8cd6cSFrank Schaefer em28xx_warn("R05 returned 0x%02x: I2C ACK error\n", 132d845fb3aSMauro Carvalho Chehab ret); 133e63b009dSMauro Carvalho Chehab return -ENXIO; 1344b83626aSMauro Carvalho Chehab } 1354b83626aSMauro Carvalho Chehab if (ret < 0) { 136d230d5adSFrank Schaefer em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 137d230d5adSFrank Schaefer ret); 1380c0d06caSMauro Carvalho Chehab return ret; 1390c0d06caSMauro Carvalho Chehab } 1402fcc82d8SFrank Schaefer msleep(5); 1412fcc82d8SFrank Schaefer } 14250f0a9dfSMauro Carvalho Chehab if (ret != 0x84 + len - 1) { 14350f0a9dfSMauro Carvalho Chehab if (i2c_debug) 14450f0a9dfSMauro Carvalho Chehab em28xx_warn("read from i2c device at 0x%x timed out\n", 14550f0a9dfSMauro Carvalho Chehab addr); 14650f0a9dfSMauro Carvalho Chehab } 1472fcc82d8SFrank Schaefer 1482fcc82d8SFrank Schaefer /* get the received message */ 1492fcc82d8SFrank Schaefer ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); 1502fcc82d8SFrank Schaefer if (ret != len) { 151d230d5adSFrank Schaefer em28xx_warn("reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", 152d230d5adSFrank Schaefer addr, ret); 1532fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1542fcc82d8SFrank Schaefer } 1552fcc82d8SFrank Schaefer for (i = 0; i < len; i++) 1562fcc82d8SFrank Schaefer buf[i] = buf2[len - 1 - i]; 1572fcc82d8SFrank Schaefer 1580c0d06caSMauro Carvalho Chehab return ret; 1590c0d06caSMauro Carvalho Chehab } 1602fcc82d8SFrank Schaefer 1612fcc82d8SFrank Schaefer /* 1622fcc82d8SFrank Schaefer * em2800_i2c_check_for_device() 1632fcc82d8SFrank Schaefer * check if there is an i2c device at the supplied address 1642fcc82d8SFrank Schaefer */ 1652fcc82d8SFrank Schaefer static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) 1662fcc82d8SFrank Schaefer { 1672fcc82d8SFrank Schaefer u8 buf; 1682fcc82d8SFrank Schaefer int ret; 1692fcc82d8SFrank Schaefer 1702fcc82d8SFrank Schaefer ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1); 1712fcc82d8SFrank Schaefer if (ret == 1) 1722fcc82d8SFrank Schaefer return 0; 1732fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1740c0d06caSMauro Carvalho Chehab } 1750c0d06caSMauro Carvalho Chehab 1760c0d06caSMauro Carvalho Chehab /* 1770c0d06caSMauro Carvalho Chehab * em28xx_i2c_send_bytes() 1780c0d06caSMauro Carvalho Chehab */ 179a6bad040SFrank Schaefer static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, 180a6bad040SFrank Schaefer u16 len, int stop) 1810c0d06caSMauro Carvalho Chehab { 182d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 1834b83626aSMauro Carvalho Chehab int ret; 1840c0d06caSMauro Carvalho Chehab 185f5ae371aSFrank Schaefer if (len < 1 || len > 64) 186f5ae371aSFrank Schaefer return -EOPNOTSUPP; 187fa74aca3SFrank Schaefer /* 188fa74aca3SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 189fa74aca3SFrank Schaefer * Zero length reads always succeed, even if no device is connected 190fa74aca3SFrank Schaefer */ 191f5ae371aSFrank Schaefer 19245f04e82SFrank Schaefer /* Write to i2c device */ 19345f04e82SFrank Schaefer ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); 19445f04e82SFrank Schaefer if (ret != len) { 19545f04e82SFrank Schaefer if (ret < 0) { 196d230d5adSFrank Schaefer em28xx_warn("writing to i2c device at 0x%x failed (error=%i)\n", 197d230d5adSFrank Schaefer addr, ret); 19845f04e82SFrank Schaefer return ret; 19945f04e82SFrank Schaefer } else { 200d230d5adSFrank Schaefer em28xx_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", 20145f04e82SFrank Schaefer len, addr, ret); 20245f04e82SFrank Schaefer return -EIO; 20345f04e82SFrank Schaefer } 20445f04e82SFrank Schaefer } 2050c0d06caSMauro Carvalho Chehab 2064b83626aSMauro Carvalho Chehab /* wait for completion */ 2074b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 2080c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg(dev, 0x05); 2094b83626aSMauro Carvalho Chehab if (ret == 0) /* success */ 21045f04e82SFrank Schaefer return len; 2114b83626aSMauro Carvalho Chehab if (ret == 0x10) { 212d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 2138ae8cd6cSFrank Schaefer em28xx_warn("I2C ACK error on writing to addr 0x%02x\n", 214d845fb3aSMauro Carvalho Chehab addr); 215e63b009dSMauro Carvalho Chehab return -ENXIO; 2164b83626aSMauro Carvalho Chehab } 2174b83626aSMauro Carvalho Chehab if (ret < 0) { 2184b83626aSMauro Carvalho Chehab em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 219d230d5adSFrank Schaefer ret); 22045f04e82SFrank Schaefer return ret; 2210c0d06caSMauro Carvalho Chehab } 22245f04e82SFrank Schaefer msleep(5); 223fa74aca3SFrank Schaefer /* 224fa74aca3SFrank Schaefer * NOTE: do we really have to wait for success ? 225fa74aca3SFrank Schaefer * Never seen anything else than 0x00 or 0x10 226fa74aca3SFrank Schaefer * (even with high payload) ... 227fa74aca3SFrank Schaefer */ 22845f04e82SFrank Schaefer } 229*123a17d1SFrank Schaefer 230*123a17d1SFrank Schaefer if (ret == 0x02 || ret == 0x04) { 231*123a17d1SFrank Schaefer /* NOTE: these errors seem to be related to clock stretching */ 23250f0a9dfSMauro Carvalho Chehab if (i2c_debug) 23350f0a9dfSMauro Carvalho Chehab em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n", 23450f0a9dfSMauro Carvalho Chehab addr, ret); 235e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 2360c0d06caSMauro Carvalho Chehab } 2370c0d06caSMauro Carvalho Chehab 238*123a17d1SFrank Schaefer em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", 239*123a17d1SFrank Schaefer addr, ret); 240*123a17d1SFrank Schaefer return -EIO; 241*123a17d1SFrank Schaefer } 242*123a17d1SFrank Schaefer 2430c0d06caSMauro Carvalho Chehab /* 2440c0d06caSMauro Carvalho Chehab * em28xx_i2c_recv_bytes() 2450c0d06caSMauro Carvalho Chehab * read a byte from the i2c device 2460c0d06caSMauro Carvalho Chehab */ 247a6bad040SFrank Schaefer static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) 2480c0d06caSMauro Carvalho Chehab { 2490c0d06caSMauro Carvalho Chehab int ret; 250f5ae371aSFrank Schaefer 251f5ae371aSFrank Schaefer if (len < 1 || len > 64) 252f5ae371aSFrank Schaefer return -EOPNOTSUPP; 253fa74aca3SFrank Schaefer /* 254fa74aca3SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 255fa74aca3SFrank Schaefer * Zero length reads always succeed, even if no device is connected 256fa74aca3SFrank Schaefer */ 257f5ae371aSFrank Schaefer 25845f04e82SFrank Schaefer /* Read data from i2c device */ 2590c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); 2600c0d06caSMauro Carvalho Chehab if (ret < 0) { 2617f6301d1SFrank Schaefer em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", 2627f6301d1SFrank Schaefer addr, ret); 26345f04e82SFrank Schaefer return ret; 26445f04e82SFrank Schaefer } 265fa74aca3SFrank Schaefer /* 266fa74aca3SFrank Schaefer * NOTE: some devices with two i2c busses have the bad habit to return 0 2677f6301d1SFrank Schaefer * bytes if we are on bus B AND there was no write attempt to the 2687f6301d1SFrank Schaefer * specified slave address before AND no device is present at the 2697f6301d1SFrank Schaefer * requested slave address. 270e63b009dSMauro Carvalho Chehab * Anyway, the next check will fail with -ENXIO in this case, so avoid 2717f6301d1SFrank Schaefer * spamming the system log on device probing and do nothing here. 2727f6301d1SFrank Schaefer */ 27345f04e82SFrank Schaefer 27445f04e82SFrank Schaefer /* Check success of the i2c operation */ 27545f04e82SFrank Schaefer ret = dev->em28xx_read_reg(dev, 0x05); 2764b83626aSMauro Carvalho Chehab if (ret == 0) /* success */ 2774b83626aSMauro Carvalho Chehab return len; 27845f04e82SFrank Schaefer if (ret < 0) { 2794b83626aSMauro Carvalho Chehab em28xx_warn("failed to get i2c transfer status from bridge register (error=%i)\n", 280d230d5adSFrank Schaefer ret); 2810c0d06caSMauro Carvalho Chehab return ret; 2820c0d06caSMauro Carvalho Chehab } 283d845fb3aSMauro Carvalho Chehab if (ret == 0x10) { 284d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 2858ae8cd6cSFrank Schaefer em28xx_warn("I2C ACK error on writing to addr 0x%02x\n", 286d845fb3aSMauro Carvalho Chehab addr); 287e63b009dSMauro Carvalho Chehab return -ENXIO; 288d845fb3aSMauro Carvalho Chehab } 2894b83626aSMauro Carvalho Chehab 290*123a17d1SFrank Schaefer if (ret == 0x02 || ret == 0x04) { 291*123a17d1SFrank Schaefer /* NOTE: these errors seem to be related to clock stretching */ 292*123a17d1SFrank Schaefer if (i2c_debug) 293*123a17d1SFrank Schaefer em28xx_warn("write to i2c device at 0x%x timed out (status=%i)\n", 294*123a17d1SFrank Schaefer addr, ret); 295e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 29645f04e82SFrank Schaefer } 2970c0d06caSMauro Carvalho Chehab 298*123a17d1SFrank Schaefer em28xx_warn("write to i2c device at 0x%x failed with unknown error (status=%i)\n", 299*123a17d1SFrank Schaefer addr, ret); 300*123a17d1SFrank Schaefer return -EIO; 301*123a17d1SFrank Schaefer } 302*123a17d1SFrank Schaefer 3030c0d06caSMauro Carvalho Chehab /* 3040c0d06caSMauro Carvalho Chehab * em28xx_i2c_check_for_device() 3050c0d06caSMauro Carvalho Chehab * check if there is a i2c_device at the supplied address 3060c0d06caSMauro Carvalho Chehab */ 307a6bad040SFrank Schaefer static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr) 3080c0d06caSMauro Carvalho Chehab { 3090c0d06caSMauro Carvalho Chehab int ret; 31045f04e82SFrank Schaefer u8 buf; 3110c0d06caSMauro Carvalho Chehab 31245f04e82SFrank Schaefer ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1); 31345f04e82SFrank Schaefer if (ret == 1) 3140c0d06caSMauro Carvalho Chehab return 0; 31545f04e82SFrank Schaefer return (ret < 0) ? ret : -EIO; 3160c0d06caSMauro Carvalho Chehab } 3170c0d06caSMauro Carvalho Chehab 3180c0d06caSMauro Carvalho Chehab /* 319a3ea4bf9SFrank Schaefer * em25xx_bus_B_send_bytes 320a3ea4bf9SFrank Schaefer * write bytes to the i2c device 321a3ea4bf9SFrank Schaefer */ 322a3ea4bf9SFrank Schaefer static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, 323a3ea4bf9SFrank Schaefer u16 len) 324a3ea4bf9SFrank Schaefer { 325a3ea4bf9SFrank Schaefer int ret; 326a3ea4bf9SFrank Schaefer 327a3ea4bf9SFrank Schaefer if (len < 1 || len > 64) 328a3ea4bf9SFrank Schaefer return -EOPNOTSUPP; 329a3ea4bf9SFrank Schaefer /* 330a3ea4bf9SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 331a3ea4bf9SFrank Schaefer * Zero length reads always succeed, even if no device is connected 332a3ea4bf9SFrank Schaefer */ 333a3ea4bf9SFrank Schaefer 334a3ea4bf9SFrank Schaefer /* Set register and write value */ 335a3ea4bf9SFrank Schaefer ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len); 336a3ea4bf9SFrank Schaefer if (ret != len) { 337a3ea4bf9SFrank Schaefer if (ret < 0) { 338a3ea4bf9SFrank Schaefer em28xx_warn("writing to i2c device at 0x%x failed (error=%i)\n", 339a3ea4bf9SFrank Schaefer addr, ret); 340a3ea4bf9SFrank Schaefer return ret; 341a3ea4bf9SFrank Schaefer } else { 342a3ea4bf9SFrank Schaefer em28xx_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", 343a3ea4bf9SFrank Schaefer len, addr, ret); 344a3ea4bf9SFrank Schaefer return -EIO; 345a3ea4bf9SFrank Schaefer } 346a3ea4bf9SFrank Schaefer } 347a3ea4bf9SFrank Schaefer /* Check success */ 348a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); 349a3ea4bf9SFrank Schaefer /* 350a3ea4bf9SFrank Schaefer * NOTE: the only error we've seen so far is 351a3ea4bf9SFrank Schaefer * 0x01 when the slave device is not present 352a3ea4bf9SFrank Schaefer */ 353a3ea4bf9SFrank Schaefer if (!ret) 354a3ea4bf9SFrank Schaefer return len; 355d845fb3aSMauro Carvalho Chehab else if (ret > 0) { 356d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 3578ae8cd6cSFrank Schaefer em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", 358d845fb3aSMauro Carvalho Chehab ret); 359e63b009dSMauro Carvalho Chehab return -ENXIO; 360d845fb3aSMauro Carvalho Chehab } 361a3ea4bf9SFrank Schaefer 362a3ea4bf9SFrank Schaefer return ret; 363a3ea4bf9SFrank Schaefer /* 364a3ea4bf9SFrank Schaefer * NOTE: With chip types (other chip IDs) which actually don't support 365a3ea4bf9SFrank Schaefer * this operation, it seems to succeed ALWAYS ! (even if there is no 366a3ea4bf9SFrank Schaefer * slave device or even no second i2c bus provided) 367a3ea4bf9SFrank Schaefer */ 368a3ea4bf9SFrank Schaefer } 369a3ea4bf9SFrank Schaefer 370a3ea4bf9SFrank Schaefer /* 371a3ea4bf9SFrank Schaefer * em25xx_bus_B_recv_bytes 372a3ea4bf9SFrank Schaefer * read bytes from the i2c device 373a3ea4bf9SFrank Schaefer */ 374a3ea4bf9SFrank Schaefer static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, 375a3ea4bf9SFrank Schaefer u16 len) 376a3ea4bf9SFrank Schaefer { 377a3ea4bf9SFrank Schaefer int ret; 378a3ea4bf9SFrank Schaefer 379a3ea4bf9SFrank Schaefer if (len < 1 || len > 64) 380a3ea4bf9SFrank Schaefer return -EOPNOTSUPP; 381a3ea4bf9SFrank Schaefer /* 382a3ea4bf9SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 383a3ea4bf9SFrank Schaefer * Zero length reads always succeed, even if no device is connected 384a3ea4bf9SFrank Schaefer */ 385a3ea4bf9SFrank Schaefer 386a3ea4bf9SFrank Schaefer /* Read value */ 387a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); 388a3ea4bf9SFrank Schaefer if (ret < 0) { 389a3ea4bf9SFrank Schaefer em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n", 390a3ea4bf9SFrank Schaefer addr, ret); 391a3ea4bf9SFrank Schaefer return ret; 392a3ea4bf9SFrank Schaefer } 393a3ea4bf9SFrank Schaefer /* 394a3ea4bf9SFrank Schaefer * NOTE: some devices with two i2c busses have the bad habit to return 0 395a3ea4bf9SFrank Schaefer * bytes if we are on bus B AND there was no write attempt to the 396a3ea4bf9SFrank Schaefer * specified slave address before AND no device is present at the 397a3ea4bf9SFrank Schaefer * requested slave address. 398e63b009dSMauro Carvalho Chehab * Anyway, the next check will fail with -ENXIO in this case, so avoid 399a3ea4bf9SFrank Schaefer * spamming the system log on device probing and do nothing here. 400a3ea4bf9SFrank Schaefer */ 401a3ea4bf9SFrank Schaefer 402a3ea4bf9SFrank Schaefer /* Check success */ 403a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); 404a3ea4bf9SFrank Schaefer /* 405a3ea4bf9SFrank Schaefer * NOTE: the only error we've seen so far is 406a3ea4bf9SFrank Schaefer * 0x01 when the slave device is not present 407a3ea4bf9SFrank Schaefer */ 408a3ea4bf9SFrank Schaefer if (!ret) 409a3ea4bf9SFrank Schaefer return len; 410d845fb3aSMauro Carvalho Chehab else if (ret > 0) { 411d845fb3aSMauro Carvalho Chehab if (i2c_debug == 1) 4128ae8cd6cSFrank Schaefer em28xx_warn("Bus B R08 returned 0x%02x: I2C ACK error\n", 413d845fb3aSMauro Carvalho Chehab ret); 414e63b009dSMauro Carvalho Chehab return -ENXIO; 415d845fb3aSMauro Carvalho Chehab } 416a3ea4bf9SFrank Schaefer 417a3ea4bf9SFrank Schaefer return ret; 418a3ea4bf9SFrank Schaefer /* 419a3ea4bf9SFrank Schaefer * NOTE: With chip types (other chip IDs) which actually don't support 420a3ea4bf9SFrank Schaefer * this operation, it seems to succeed ALWAYS ! (even if there is no 421a3ea4bf9SFrank Schaefer * slave device or even no second i2c bus provided) 422a3ea4bf9SFrank Schaefer */ 423a3ea4bf9SFrank Schaefer } 424a3ea4bf9SFrank Schaefer 425a3ea4bf9SFrank Schaefer /* 426a3ea4bf9SFrank Schaefer * em25xx_bus_B_check_for_device() 427a3ea4bf9SFrank Schaefer * check if there is a i2c device at the supplied address 428a3ea4bf9SFrank Schaefer */ 429a3ea4bf9SFrank Schaefer static int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr) 430a3ea4bf9SFrank Schaefer { 431a3ea4bf9SFrank Schaefer u8 buf; 432a3ea4bf9SFrank Schaefer int ret; 433a3ea4bf9SFrank Schaefer 434a3ea4bf9SFrank Schaefer ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1); 435a3ea4bf9SFrank Schaefer if (ret < 0) 436a3ea4bf9SFrank Schaefer return ret; 437a3ea4bf9SFrank Schaefer 438a3ea4bf9SFrank Schaefer return 0; 439a3ea4bf9SFrank Schaefer /* 440a3ea4bf9SFrank Schaefer * NOTE: With chips which do not support this operation, 441a3ea4bf9SFrank Schaefer * it seems to succeed ALWAYS ! (even if no device connected) 442a3ea4bf9SFrank Schaefer */ 443a3ea4bf9SFrank Schaefer } 444a3ea4bf9SFrank Schaefer 445a3ea4bf9SFrank Schaefer static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr) 446a3ea4bf9SFrank Schaefer { 447a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 448a3ea4bf9SFrank Schaefer int rc = -EOPNOTSUPP; 449a3ea4bf9SFrank Schaefer 450a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 451a3ea4bf9SFrank Schaefer rc = em28xx_i2c_check_for_device(dev, addr); 452a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 453a3ea4bf9SFrank Schaefer rc = em2800_i2c_check_for_device(dev, addr); 454a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 455a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_check_for_device(dev, addr); 456a3ea4bf9SFrank Schaefer return rc; 457a3ea4bf9SFrank Schaefer } 458a3ea4bf9SFrank Schaefer 459a3ea4bf9SFrank Schaefer static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus, 460a3ea4bf9SFrank Schaefer struct i2c_msg msg) 461a3ea4bf9SFrank Schaefer { 462a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 463a3ea4bf9SFrank Schaefer u16 addr = msg.addr << 1; 46450f0a9dfSMauro Carvalho Chehab int rc = -EOPNOTSUPP; 465a3ea4bf9SFrank Schaefer 466a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 467a3ea4bf9SFrank Schaefer rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 468a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 469a3ea4bf9SFrank Schaefer rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 470a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 471a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len); 472a3ea4bf9SFrank Schaefer return rc; 473a3ea4bf9SFrank Schaefer } 474a3ea4bf9SFrank Schaefer 475a3ea4bf9SFrank Schaefer static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus, 476a3ea4bf9SFrank Schaefer struct i2c_msg msg, int stop) 477a3ea4bf9SFrank Schaefer { 478a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 479a3ea4bf9SFrank Schaefer u16 addr = msg.addr << 1; 48050f0a9dfSMauro Carvalho Chehab int rc = -EOPNOTSUPP; 481a3ea4bf9SFrank Schaefer 482a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 483a3ea4bf9SFrank Schaefer rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop); 484a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 485a3ea4bf9SFrank Schaefer rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len); 486a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 487a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len); 488a3ea4bf9SFrank Schaefer return rc; 489a3ea4bf9SFrank Schaefer } 490a3ea4bf9SFrank Schaefer 491a3ea4bf9SFrank Schaefer /* 4920c0d06caSMauro Carvalho Chehab * em28xx_i2c_xfer() 4930c0d06caSMauro Carvalho Chehab * the main i2c transfer function 4940c0d06caSMauro Carvalho Chehab */ 4950c0d06caSMauro Carvalho Chehab static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, 4960c0d06caSMauro Carvalho Chehab struct i2c_msg msgs[], int num) 4970c0d06caSMauro Carvalho Chehab { 498aab3125cSMauro Carvalho Chehab struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 499aab3125cSMauro Carvalho Chehab struct em28xx *dev = i2c_bus->dev; 500aab3125cSMauro Carvalho Chehab unsigned bus = i2c_bus->bus; 501a3ea4bf9SFrank Schaefer int addr, rc, i; 5023190fbeeSMauro Carvalho Chehab u8 reg; 5030c0d06caSMauro Carvalho Chehab 504aab3125cSMauro Carvalho Chehab rc = rt_mutex_trylock(&dev->i2c_bus_lock); 505aab3125cSMauro Carvalho Chehab if (rc < 0) 506aab3125cSMauro Carvalho Chehab return rc; 507aab3125cSMauro Carvalho Chehab 508aab3125cSMauro Carvalho Chehab /* Switch I2C bus if needed */ 509a3ea4bf9SFrank Schaefer if (bus != dev->cur_i2c_bus && 510a3ea4bf9SFrank Schaefer i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) { 511aab3125cSMauro Carvalho Chehab if (bus == 1) 5123190fbeeSMauro Carvalho Chehab reg = EM2874_I2C_SECONDARY_BUS_SELECT; 513aab3125cSMauro Carvalho Chehab else 5143190fbeeSMauro Carvalho Chehab reg = 0; 5153190fbeeSMauro Carvalho Chehab em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg, 5163190fbeeSMauro Carvalho Chehab EM2874_I2C_SECONDARY_BUS_SELECT); 517aab3125cSMauro Carvalho Chehab dev->cur_i2c_bus = bus; 518aab3125cSMauro Carvalho Chehab } 519aab3125cSMauro Carvalho Chehab 520aab3125cSMauro Carvalho Chehab if (num <= 0) { 521aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 5220c0d06caSMauro Carvalho Chehab return 0; 523aab3125cSMauro Carvalho Chehab } 5240c0d06caSMauro Carvalho Chehab for (i = 0; i < num; i++) { 5250c0d06caSMauro Carvalho Chehab addr = msgs[i].addr << 1; 52650f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 527d7a80eaaSFrank Schaefer printk(KERN_DEBUG "%s at %s: %s %s addr=%02x len=%d:", 528d7a80eaaSFrank Schaefer dev->name, __func__ , 5290c0d06caSMauro Carvalho Chehab (msgs[i].flags & I2C_M_RD) ? "read" : "write", 530d7a80eaaSFrank Schaefer i == num - 1 ? "stop" : "nonstop", 531d7a80eaaSFrank Schaefer addr, msgs[i].len); 532e63b009dSMauro Carvalho Chehab if (!msgs[i].len) { 533e63b009dSMauro Carvalho Chehab /* 534e63b009dSMauro Carvalho Chehab * no len: check only for device presence 535e63b009dSMauro Carvalho Chehab * This code is only called during device probe. 536e63b009dSMauro Carvalho Chehab */ 537a3ea4bf9SFrank Schaefer rc = i2c_check_for_device(i2c_bus, addr); 53850f0a9dfSMauro Carvalho Chehab if (rc < 0) { 539e63b009dSMauro Carvalho Chehab if (rc == -ENXIO) { 54050f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 54150f0a9dfSMauro Carvalho Chehab printk(KERN_CONT " no device\n"); 54250f0a9dfSMauro Carvalho Chehab rc = -ENODEV; 54350f0a9dfSMauro Carvalho Chehab } else { 54450f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 54550f0a9dfSMauro Carvalho Chehab printk(KERN_CONT " ERROR: %i\n", rc); 54650f0a9dfSMauro Carvalho Chehab } 547aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 54850f0a9dfSMauro Carvalho Chehab return rc; 5490c0d06caSMauro Carvalho Chehab } 5500c0d06caSMauro Carvalho Chehab } else if (msgs[i].flags & I2C_M_RD) { 5510c0d06caSMauro Carvalho Chehab /* read bytes */ 552a3ea4bf9SFrank Schaefer rc = i2c_recv_bytes(i2c_bus, msgs[i]); 55350f0a9dfSMauro Carvalho Chehab 55450f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1 && rc >= 0) 55550f0a9dfSMauro Carvalho Chehab printk(KERN_CONT " %*ph", 55650f0a9dfSMauro Carvalho Chehab msgs[i].len, msgs[i].buf); 5570c0d06caSMauro Carvalho Chehab } else { 55850f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 55950f0a9dfSMauro Carvalho Chehab printk(KERN_CONT " %*ph", 56050f0a9dfSMauro Carvalho Chehab msgs[i].len, msgs[i].buf); 56150f0a9dfSMauro Carvalho Chehab 5620c0d06caSMauro Carvalho Chehab /* write bytes */ 563a3ea4bf9SFrank Schaefer rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1); 5640c0d06caSMauro Carvalho Chehab } 56545f04e82SFrank Schaefer if (rc < 0) { 56650f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 56750f0a9dfSMauro Carvalho Chehab printk(KERN_CONT " ERROR: %i\n", rc); 568aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 56945f04e82SFrank Schaefer return rc; 57045f04e82SFrank Schaefer } 57150f0a9dfSMauro Carvalho Chehab if (i2c_debug > 1) 57250f0a9dfSMauro Carvalho Chehab printk(KERN_CONT "\n"); 5730c0d06caSMauro Carvalho Chehab } 5740c0d06caSMauro Carvalho Chehab 575aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 5760c0d06caSMauro Carvalho Chehab return num; 5770c0d06caSMauro Carvalho Chehab } 5780c0d06caSMauro Carvalho Chehab 579fa74aca3SFrank Schaefer /* 580fa74aca3SFrank Schaefer * based on linux/sunrpc/svcauth.h and linux/hash.h 5810c0d06caSMauro Carvalho Chehab * The original hash function returns a different value, if arch is x86_64 5820c0d06caSMauro Carvalho Chehab * or i386. 5830c0d06caSMauro Carvalho Chehab */ 5840c0d06caSMauro Carvalho Chehab static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) 5850c0d06caSMauro Carvalho Chehab { 5860c0d06caSMauro Carvalho Chehab unsigned long hash = 0; 5870c0d06caSMauro Carvalho Chehab unsigned long l = 0; 5880c0d06caSMauro Carvalho Chehab int len = 0; 5890c0d06caSMauro Carvalho Chehab unsigned char c; 5900c0d06caSMauro Carvalho Chehab do { 5910c0d06caSMauro Carvalho Chehab if (len == length) { 5920c0d06caSMauro Carvalho Chehab c = (char)len; 5930c0d06caSMauro Carvalho Chehab len = -1; 5940c0d06caSMauro Carvalho Chehab } else 5950c0d06caSMauro Carvalho Chehab c = *buf++; 5960c0d06caSMauro Carvalho Chehab l = (l << 8) | c; 5970c0d06caSMauro Carvalho Chehab len++; 5980c0d06caSMauro Carvalho Chehab if ((len & (32 / 8 - 1)) == 0) 5990c0d06caSMauro Carvalho Chehab hash = ((hash^l) * 0x9e370001UL); 6000c0d06caSMauro Carvalho Chehab } while (len); 6010c0d06caSMauro Carvalho Chehab 6020c0d06caSMauro Carvalho Chehab return (hash >> (32 - bits)) & 0xffffffffUL; 6030c0d06caSMauro Carvalho Chehab } 6040c0d06caSMauro Carvalho Chehab 605fa74aca3SFrank Schaefer /* 606fa74aca3SFrank Schaefer * Helper function to read data blocks from i2c clients with 8 or 16 bit 607fa74aca3SFrank Schaefer * address width, 8 bit register width and auto incrementation been activated 608fa74aca3SFrank Schaefer */ 609aab3125cSMauro Carvalho Chehab static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, 610aab3125cSMauro Carvalho Chehab bool addr_w16, u16 len, u8 *data) 611d832c5b2SFrank Schaefer { 612d832c5b2SFrank Schaefer int remain = len, rsize, rsize_max, ret; 613d832c5b2SFrank Schaefer u8 buf[2]; 614d832c5b2SFrank Schaefer 615d832c5b2SFrank Schaefer /* Sanity check */ 616d832c5b2SFrank Schaefer if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1)) 617d832c5b2SFrank Schaefer return -EINVAL; 618d832c5b2SFrank Schaefer /* Select address */ 619d832c5b2SFrank Schaefer buf[0] = addr >> 8; 620d832c5b2SFrank Schaefer buf[1] = addr & 0xff; 621aab3125cSMauro Carvalho Chehab ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); 622d832c5b2SFrank Schaefer if (ret < 0) 623d832c5b2SFrank Schaefer return ret; 624d832c5b2SFrank Schaefer /* Read data */ 625d832c5b2SFrank Schaefer if (dev->board.is_em2800) 626d832c5b2SFrank Schaefer rsize_max = 4; 627d832c5b2SFrank Schaefer else 628d832c5b2SFrank Schaefer rsize_max = 64; 629d832c5b2SFrank Schaefer while (remain > 0) { 630d832c5b2SFrank Schaefer if (remain > rsize_max) 631d832c5b2SFrank Schaefer rsize = rsize_max; 632d832c5b2SFrank Schaefer else 633d832c5b2SFrank Schaefer rsize = remain; 634d832c5b2SFrank Schaefer 635aab3125cSMauro Carvalho Chehab ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize); 636d832c5b2SFrank Schaefer if (ret < 0) 637d832c5b2SFrank Schaefer return ret; 638d832c5b2SFrank Schaefer 639d832c5b2SFrank Schaefer remain -= rsize; 640d832c5b2SFrank Schaefer data += rsize; 641d832c5b2SFrank Schaefer } 642d832c5b2SFrank Schaefer 643d832c5b2SFrank Schaefer return len; 644d832c5b2SFrank Schaefer } 645d832c5b2SFrank Schaefer 646aab3125cSMauro Carvalho Chehab static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, 647aab3125cSMauro Carvalho Chehab u8 **eedata, u16 *eedata_len) 6480c0d06caSMauro Carvalho Chehab { 649510e884cSFrank Schaefer const u16 len = 256; 650fa74aca3SFrank Schaefer /* 651fa74aca3SFrank Schaefer * FIXME common length/size for bytes to read, to display, hash 652510e884cSFrank Schaefer * calculation and returned device dataset. Simplifies the code a lot, 653fa74aca3SFrank Schaefer * but we might have to deal with multiple sizes in the future ! 654fa74aca3SFrank Schaefer */ 65550f0a9dfSMauro Carvalho Chehab int err; 656510e884cSFrank Schaefer struct em28xx_eeprom *dev_config; 657510e884cSFrank Schaefer u8 buf, *data; 6580c0d06caSMauro Carvalho Chehab 659a217968fSFrank Schaefer *eedata = NULL; 660510e884cSFrank Schaefer *eedata_len = 0; 661a217968fSFrank Schaefer 662aab3125cSMauro Carvalho Chehab /* EEPROM is always on i2c bus 0 on all known devices. */ 663aab3125cSMauro Carvalho Chehab 664aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].addr = 0xa0 >> 1; 6650c0d06caSMauro Carvalho Chehab 6660c0d06caSMauro Carvalho Chehab /* Check if board has eeprom */ 667aab3125cSMauro Carvalho Chehab err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); 6680c0d06caSMauro Carvalho Chehab if (err < 0) { 66912d7ce18SFrank Schaefer em28xx_info("board has no eeprom\n"); 6700c0d06caSMauro Carvalho Chehab return -ENODEV; 6710c0d06caSMauro Carvalho Chehab } 6720c0d06caSMauro Carvalho Chehab 673a217968fSFrank Schaefer data = kzalloc(len, GFP_KERNEL); 674a217968fSFrank Schaefer if (data == NULL) 675a217968fSFrank Schaefer return -ENOMEM; 676a217968fSFrank Schaefer 677d832c5b2SFrank Schaefer /* Read EEPROM content */ 678aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, 0x0000, 679aab3125cSMauro Carvalho Chehab dev->eeprom_addrwidth_16bit, 680a217968fSFrank Schaefer len, data); 681d832c5b2SFrank Schaefer if (err != len) { 68212d7ce18SFrank Schaefer em28xx_errdev("failed to read eeprom (err=%d)\n", err); 683510e884cSFrank Schaefer goto error; 6840c0d06caSMauro Carvalho Chehab } 68590271964SFrank Schaefer 68650f0a9dfSMauro Carvalho Chehab if (i2c_debug) { 68787b52439SFrank Schaefer /* Display eeprom content */ 68850f0a9dfSMauro Carvalho Chehab print_hex_dump(KERN_INFO, "eeprom ", DUMP_PREFIX_OFFSET, 68950f0a9dfSMauro Carvalho Chehab 16, 1, data, len, true); 69050f0a9dfSMauro Carvalho Chehab 69187b52439SFrank Schaefer if (dev->eeprom_addrwidth_16bit) 69250f0a9dfSMauro Carvalho Chehab em28xx_info("eeprom %06x: ... (skipped)\n", 256); 69387b52439SFrank Schaefer } 6940c0d06caSMauro Carvalho Chehab 69587b52439SFrank Schaefer if (dev->eeprom_addrwidth_16bit && 696a217968fSFrank Schaefer data[0] == 0x26 && data[3] == 0x00) { 69787b52439SFrank Schaefer /* new eeprom format; size 4-64kb */ 698510e884cSFrank Schaefer u16 mc_start; 699510e884cSFrank Schaefer u16 hwconf_offset; 700510e884cSFrank Schaefer 701a217968fSFrank Schaefer dev->hash = em28xx_hash_mem(data, len, 32); 702510e884cSFrank Schaefer mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ 703510e884cSFrank Schaefer 704d230d5adSFrank Schaefer em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", 705510e884cSFrank Schaefer data[0], data[1], data[2], data[3], dev->hash); 706510e884cSFrank Schaefer em28xx_info("EEPROM info:\n"); 707d230d5adSFrank Schaefer em28xx_info("\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", 708510e884cSFrank Schaefer mc_start, data[2]); 709fa74aca3SFrank Schaefer /* 710fa74aca3SFrank Schaefer * boot configuration (address 0x0002): 71187b52439SFrank Schaefer * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz 71287b52439SFrank Schaefer * [1] always selects 12 kb RAM 71387b52439SFrank Schaefer * [2] USB device speed: 1 = force Full Speed; 0 = auto detect 71487b52439SFrank Schaefer * [4] 1 = force fast mode and no suspend for device testing 71587b52439SFrank Schaefer * [5:7] USB PHY tuning registers; determined by device 71687b52439SFrank Schaefer * characterization 71787b52439SFrank Schaefer */ 71887b52439SFrank Schaefer 719fa74aca3SFrank Schaefer /* 720fa74aca3SFrank Schaefer * Read hardware config dataset offset from address 721fa74aca3SFrank Schaefer * (microcode start + 46) 722fa74aca3SFrank Schaefer */ 723aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, 724aab3125cSMauro Carvalho Chehab data); 725510e884cSFrank Schaefer if (err != 2) { 726510e884cSFrank Schaefer em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", 727510e884cSFrank Schaefer err); 728510e884cSFrank Schaefer goto error; 729510e884cSFrank Schaefer } 73087b52439SFrank Schaefer 731510e884cSFrank Schaefer /* Calculate hardware config dataset start address */ 732510e884cSFrank Schaefer hwconf_offset = mc_start + data[0] + (data[1] << 8); 733510e884cSFrank Schaefer 734510e884cSFrank Schaefer /* Read hardware config dataset */ 735fa74aca3SFrank Schaefer /* 736fa74aca3SFrank Schaefer * NOTE: the microcode copy can be multiple pages long, but 737510e884cSFrank Schaefer * we assume the hardware config dataset is the same as in 738510e884cSFrank Schaefer * the old eeprom and not longer than 256 bytes. 739510e884cSFrank Schaefer * tveeprom is currently also limited to 256 bytes. 740510e884cSFrank Schaefer */ 741aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, 742aab3125cSMauro Carvalho Chehab data); 743510e884cSFrank Schaefer if (err != len) { 744510e884cSFrank Schaefer em28xx_errdev("failed to read hardware configuration data from eeprom (err=%d)\n", 745510e884cSFrank Schaefer err); 746510e884cSFrank Schaefer goto error; 747510e884cSFrank Schaefer } 748510e884cSFrank Schaefer 749510e884cSFrank Schaefer /* Verify hardware config dataset */ 750510e884cSFrank Schaefer /* NOTE: not all devices provide this type of dataset */ 751510e884cSFrank Schaefer if (data[0] != 0x1a || data[1] != 0xeb || 752a217968fSFrank Schaefer data[2] != 0x67 || data[3] != 0x95) { 753510e884cSFrank Schaefer em28xx_info("\tno hardware configuration dataset found in eeprom\n"); 754510e884cSFrank Schaefer kfree(data); 755510e884cSFrank Schaefer return 0; 756510e884cSFrank Schaefer } 757510e884cSFrank Schaefer 758510e884cSFrank Schaefer /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ 759510e884cSFrank Schaefer 760510e884cSFrank Schaefer } else if (!dev->eeprom_addrwidth_16bit && 761510e884cSFrank Schaefer data[0] == 0x1a && data[1] == 0xeb && 762510e884cSFrank Schaefer data[2] == 0x67 && data[3] == 0x95) { 763510e884cSFrank Schaefer dev->hash = em28xx_hash_mem(data, len, 32); 764d230d5adSFrank Schaefer em28xx_info("EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", 765510e884cSFrank Schaefer data[0], data[1], data[2], data[3], dev->hash); 766510e884cSFrank Schaefer em28xx_info("EEPROM info:\n"); 767510e884cSFrank Schaefer } else { 76887b52439SFrank Schaefer em28xx_info("unknown eeprom format or eeprom corrupted !\n"); 769510e884cSFrank Schaefer err = -ENODEV; 770510e884cSFrank Schaefer goto error; 771f55eacbeSFrank Schaefer } 772f55eacbeSFrank Schaefer 773a217968fSFrank Schaefer *eedata = data; 774510e884cSFrank Schaefer *eedata_len = len; 77532bf7c6cSAlban Browaeys dev_config = (void *)*eedata; 776a217968fSFrank Schaefer 777510e884cSFrank Schaefer switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { 7780c0d06caSMauro Carvalho Chehab case 0: 77912d7ce18SFrank Schaefer em28xx_info("\tNo audio on board.\n"); 7800c0d06caSMauro Carvalho Chehab break; 7810c0d06caSMauro Carvalho Chehab case 1: 78212d7ce18SFrank Schaefer em28xx_info("\tAC97 audio (5 sample rates)\n"); 7830c0d06caSMauro Carvalho Chehab break; 7840c0d06caSMauro Carvalho Chehab case 2: 785687ff8b0SFrank Schaefer if (dev->chip_id < CHIP_ID_EM2860) 78612d7ce18SFrank Schaefer em28xx_info("\tI2S audio, sample rate=32k\n"); 787687ff8b0SFrank Schaefer else 788687ff8b0SFrank Schaefer em28xx_info("\tI2S audio, 3 sample rates\n"); 7890c0d06caSMauro Carvalho Chehab break; 7900c0d06caSMauro Carvalho Chehab case 3: 791687ff8b0SFrank Schaefer if (dev->chip_id < CHIP_ID_EM2860) 79212d7ce18SFrank Schaefer em28xx_info("\tI2S audio, 3 sample rates\n"); 793687ff8b0SFrank Schaefer else 794687ff8b0SFrank Schaefer em28xx_info("\tI2S audio, 5 sample rates\n"); 7950c0d06caSMauro Carvalho Chehab break; 7960c0d06caSMauro Carvalho Chehab } 7970c0d06caSMauro Carvalho Chehab 798510e884cSFrank Schaefer if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) 79912d7ce18SFrank Schaefer em28xx_info("\tUSB Remote wakeup capable\n"); 8000c0d06caSMauro Carvalho Chehab 801510e884cSFrank Schaefer if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) 80212d7ce18SFrank Schaefer em28xx_info("\tUSB Self power capable\n"); 8030c0d06caSMauro Carvalho Chehab 804510e884cSFrank Schaefer switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { 8050c0d06caSMauro Carvalho Chehab case 0: 80612d7ce18SFrank Schaefer em28xx_info("\t500mA max power\n"); 8070c0d06caSMauro Carvalho Chehab break; 8080c0d06caSMauro Carvalho Chehab case 1: 80912d7ce18SFrank Schaefer em28xx_info("\t400mA max power\n"); 8100c0d06caSMauro Carvalho Chehab break; 8110c0d06caSMauro Carvalho Chehab case 2: 81212d7ce18SFrank Schaefer em28xx_info("\t300mA max power\n"); 8130c0d06caSMauro Carvalho Chehab break; 8140c0d06caSMauro Carvalho Chehab case 3: 81512d7ce18SFrank Schaefer em28xx_info("\t200mA max power\n"); 8160c0d06caSMauro Carvalho Chehab break; 8170c0d06caSMauro Carvalho Chehab } 81812d7ce18SFrank Schaefer em28xx_info("\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", 819510e884cSFrank Schaefer dev_config->string_idx_table, 820510e884cSFrank Schaefer le16_to_cpu(dev_config->string1), 821510e884cSFrank Schaefer le16_to_cpu(dev_config->string2), 822510e884cSFrank Schaefer le16_to_cpu(dev_config->string3)); 8230c0d06caSMauro Carvalho Chehab 8240c0d06caSMauro Carvalho Chehab return 0; 825510e884cSFrank Schaefer 826510e884cSFrank Schaefer error: 827510e884cSFrank Schaefer kfree(data); 828510e884cSFrank Schaefer return err; 8290c0d06caSMauro Carvalho Chehab } 8300c0d06caSMauro Carvalho Chehab 8310c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 8320c0d06caSMauro Carvalho Chehab 8330c0d06caSMauro Carvalho Chehab /* 8340c0d06caSMauro Carvalho Chehab * functionality() 8350c0d06caSMauro Carvalho Chehab */ 836aab3125cSMauro Carvalho Chehab static u32 functionality(struct i2c_adapter *i2c_adap) 8370c0d06caSMauro Carvalho Chehab { 838aab3125cSMauro Carvalho Chehab struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 839aab3125cSMauro Carvalho Chehab 840a3ea4bf9SFrank Schaefer if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) || 841a3ea4bf9SFrank Schaefer (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) { 842a3ea4bf9SFrank Schaefer return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 843a3ea4bf9SFrank Schaefer } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) { 844a3ea4bf9SFrank Schaefer return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & 845a3ea4bf9SFrank Schaefer ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; 846a3ea4bf9SFrank Schaefer } 847a3ea4bf9SFrank Schaefer 848a3ea4bf9SFrank Schaefer WARN(1, "Unknown i2c bus algorithm.\n"); 849a3ea4bf9SFrank Schaefer return 0; 8500c0d06caSMauro Carvalho Chehab } 8510c0d06caSMauro Carvalho Chehab 8520c0d06caSMauro Carvalho Chehab static struct i2c_algorithm em28xx_algo = { 8530c0d06caSMauro Carvalho Chehab .master_xfer = em28xx_i2c_xfer, 8540c0d06caSMauro Carvalho Chehab .functionality = functionality, 8550c0d06caSMauro Carvalho Chehab }; 8560c0d06caSMauro Carvalho Chehab 8570c0d06caSMauro Carvalho Chehab static struct i2c_adapter em28xx_adap_template = { 8580c0d06caSMauro Carvalho Chehab .owner = THIS_MODULE, 8590c0d06caSMauro Carvalho Chehab .name = "em28xx", 8600c0d06caSMauro Carvalho Chehab .algo = &em28xx_algo, 8610c0d06caSMauro Carvalho Chehab }; 8620c0d06caSMauro Carvalho Chehab 8630c0d06caSMauro Carvalho Chehab static struct i2c_client em28xx_client_template = { 8640c0d06caSMauro Carvalho Chehab .name = "em28xx internal", 8650c0d06caSMauro Carvalho Chehab }; 8660c0d06caSMauro Carvalho Chehab 8670c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 8680c0d06caSMauro Carvalho Chehab 8690c0d06caSMauro Carvalho Chehab /* 8700c0d06caSMauro Carvalho Chehab * i2c_devs 8710c0d06caSMauro Carvalho Chehab * incomplete list of known devices 8720c0d06caSMauro Carvalho Chehab */ 8730c0d06caSMauro Carvalho Chehab static char *i2c_devs[128] = { 8740b3966e4SFrank Schaefer [0x3e >> 1] = "remote IR sensor", 8750c0d06caSMauro Carvalho Chehab [0x4a >> 1] = "saa7113h", 8760c0d06caSMauro Carvalho Chehab [0x52 >> 1] = "drxk", 8770c0d06caSMauro Carvalho Chehab [0x60 >> 1] = "remote IR sensor", 8780c0d06caSMauro Carvalho Chehab [0x8e >> 1] = "remote IR sensor", 8790c0d06caSMauro Carvalho Chehab [0x86 >> 1] = "tda9887", 8800c0d06caSMauro Carvalho Chehab [0x80 >> 1] = "msp34xx", 8810c0d06caSMauro Carvalho Chehab [0x88 >> 1] = "msp34xx", 8820c0d06caSMauro Carvalho Chehab [0xa0 >> 1] = "eeprom", 8830c0d06caSMauro Carvalho Chehab [0xb0 >> 1] = "tda9874", 8840c0d06caSMauro Carvalho Chehab [0xb8 >> 1] = "tvp5150a", 8850c0d06caSMauro Carvalho Chehab [0xba >> 1] = "webcam sensor or tvp5150a", 8860c0d06caSMauro Carvalho Chehab [0xc0 >> 1] = "tuner (analog)", 8870c0d06caSMauro Carvalho Chehab [0xc2 >> 1] = "tuner (analog)", 8880c0d06caSMauro Carvalho Chehab [0xc4 >> 1] = "tuner (analog)", 8890c0d06caSMauro Carvalho Chehab [0xc6 >> 1] = "tuner (analog)", 8900c0d06caSMauro Carvalho Chehab }; 8910c0d06caSMauro Carvalho Chehab 8920c0d06caSMauro Carvalho Chehab /* 8930c0d06caSMauro Carvalho Chehab * do_i2c_scan() 8940c0d06caSMauro Carvalho Chehab * check i2c address range for devices 8950c0d06caSMauro Carvalho Chehab */ 896aab3125cSMauro Carvalho Chehab void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) 8970c0d06caSMauro Carvalho Chehab { 8980c0d06caSMauro Carvalho Chehab u8 i2c_devicelist[128]; 8990c0d06caSMauro Carvalho Chehab unsigned char buf; 9000c0d06caSMauro Carvalho Chehab int i, rc; 9010c0d06caSMauro Carvalho Chehab 9020c0d06caSMauro Carvalho Chehab memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); 9030c0d06caSMauro Carvalho Chehab 9040c0d06caSMauro Carvalho Chehab for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { 905aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].addr = i; 906aab3125cSMauro Carvalho Chehab rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); 9070c0d06caSMauro Carvalho Chehab if (rc < 0) 9080c0d06caSMauro Carvalho Chehab continue; 9090c0d06caSMauro Carvalho Chehab i2c_devicelist[i] = i; 910aab3125cSMauro Carvalho Chehab em28xx_info("found i2c device @ 0x%x on bus %d [%s]\n", 911aab3125cSMauro Carvalho Chehab i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); 9120c0d06caSMauro Carvalho Chehab } 9130c0d06caSMauro Carvalho Chehab 914aab3125cSMauro Carvalho Chehab if (bus == dev->def_i2c_bus) 9150c0d06caSMauro Carvalho Chehab dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, 9160c0d06caSMauro Carvalho Chehab ARRAY_SIZE(i2c_devicelist), 32); 9170c0d06caSMauro Carvalho Chehab } 9180c0d06caSMauro Carvalho Chehab 9190c0d06caSMauro Carvalho Chehab /* 9200c0d06caSMauro Carvalho Chehab * em28xx_i2c_register() 9210c0d06caSMauro Carvalho Chehab * register i2c bus 9220c0d06caSMauro Carvalho Chehab */ 923a3ea4bf9SFrank Schaefer int em28xx_i2c_register(struct em28xx *dev, unsigned bus, 924a3ea4bf9SFrank Schaefer enum em28xx_i2c_algo_type algo_type) 9250c0d06caSMauro Carvalho Chehab { 9260c0d06caSMauro Carvalho Chehab int retval; 9270c0d06caSMauro Carvalho Chehab 9280c0d06caSMauro Carvalho Chehab BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); 9290c0d06caSMauro Carvalho Chehab BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); 9300c0d06caSMauro Carvalho Chehab 931aab3125cSMauro Carvalho Chehab if (bus >= NUM_I2C_BUSES) 932aab3125cSMauro Carvalho Chehab return -ENODEV; 933aab3125cSMauro Carvalho Chehab 934aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus] = em28xx_adap_template; 935aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus].dev.parent = &dev->udev->dev; 936aab3125cSMauro Carvalho Chehab strcpy(dev->i2c_adap[bus].name, dev->name); 937aab3125cSMauro Carvalho Chehab 938aab3125cSMauro Carvalho Chehab dev->i2c_bus[bus].bus = bus; 939a3ea4bf9SFrank Schaefer dev->i2c_bus[bus].algo_type = algo_type; 940aab3125cSMauro Carvalho Chehab dev->i2c_bus[bus].dev = dev; 941aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; 942aab3125cSMauro Carvalho Chehab i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); 943aab3125cSMauro Carvalho Chehab 944aab3125cSMauro Carvalho Chehab retval = i2c_add_adapter(&dev->i2c_adap[bus]); 9450c0d06caSMauro Carvalho Chehab if (retval < 0) { 9460c0d06caSMauro Carvalho Chehab em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", 9470c0d06caSMauro Carvalho Chehab __func__, retval); 9480c0d06caSMauro Carvalho Chehab return retval; 9490c0d06caSMauro Carvalho Chehab } 9500c0d06caSMauro Carvalho Chehab 951aab3125cSMauro Carvalho Chehab dev->i2c_client[bus] = em28xx_client_template; 952aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; 9530c0d06caSMauro Carvalho Chehab 954aab3125cSMauro Carvalho Chehab /* Up to now, all eeproms are at bus 0 */ 955aab3125cSMauro Carvalho Chehab if (!bus) { 956aab3125cSMauro Carvalho Chehab retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); 9570c0d06caSMauro Carvalho Chehab if ((retval < 0) && (retval != -ENODEV)) { 9580c0d06caSMauro Carvalho Chehab em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", 9590c0d06caSMauro Carvalho Chehab __func__, retval); 9600c0d06caSMauro Carvalho Chehab 9610c0d06caSMauro Carvalho Chehab return retval; 9620c0d06caSMauro Carvalho Chehab } 963aab3125cSMauro Carvalho Chehab } 9640c0d06caSMauro Carvalho Chehab 9650c0d06caSMauro Carvalho Chehab if (i2c_scan) 966aab3125cSMauro Carvalho Chehab em28xx_do_i2c_scan(dev, bus); 9670c0d06caSMauro Carvalho Chehab 9680c0d06caSMauro Carvalho Chehab return 0; 9690c0d06caSMauro Carvalho Chehab } 9700c0d06caSMauro Carvalho Chehab 9710c0d06caSMauro Carvalho Chehab /* 9720c0d06caSMauro Carvalho Chehab * em28xx_i2c_unregister() 9730c0d06caSMauro Carvalho Chehab * unregister i2c_bus 9740c0d06caSMauro Carvalho Chehab */ 975aab3125cSMauro Carvalho Chehab int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) 9760c0d06caSMauro Carvalho Chehab { 977aab3125cSMauro Carvalho Chehab if (bus >= NUM_I2C_BUSES) 978aab3125cSMauro Carvalho Chehab return -ENODEV; 979aab3125cSMauro Carvalho Chehab 980aab3125cSMauro Carvalho Chehab i2c_del_adapter(&dev->i2c_adap[bus]); 9810c0d06caSMauro Carvalho Chehab return 0; 9820c0d06caSMauro Carvalho Chehab } 983