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 258314d402SMauro Carvalho Chehab #include "em28xx.h" 268314d402SMauro Carvalho Chehab 270c0d06caSMauro Carvalho Chehab #include <linux/module.h> 280c0d06caSMauro Carvalho Chehab #include <linux/kernel.h> 290c0d06caSMauro Carvalho Chehab #include <linux/usb.h> 300c0d06caSMauro Carvalho Chehab #include <linux/i2c.h> 314b83626aSMauro Carvalho Chehab #include <linux/jiffies.h> 320c0d06caSMauro Carvalho Chehab 330c0d06caSMauro Carvalho Chehab #include "tuner-xc2028.h" 340c0d06caSMauro Carvalho Chehab #include <media/v4l2-common.h> 350c0d06caSMauro Carvalho Chehab #include <media/tuner.h> 360c0d06caSMauro Carvalho Chehab 370c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 380c0d06caSMauro Carvalho Chehab 390c0d06caSMauro Carvalho Chehab static unsigned int i2c_scan; 400c0d06caSMauro Carvalho Chehab module_param(i2c_scan, int, 0444); 410c0d06caSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); 420c0d06caSMauro Carvalho Chehab 430c0d06caSMauro Carvalho Chehab static unsigned int i2c_debug; 440c0d06caSMauro Carvalho Chehab module_param(i2c_debug, int, 0644); 4550f0a9dfSMauro Carvalho Chehab MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)"); 460c0d06caSMauro Carvalho Chehab 47*ce8591ffSMauro Carvalho Chehab #define dprintk(level, fmt, arg...) do { \ 48*ce8591ffSMauro Carvalho Chehab if (i2c_debug > level) \ 49*ce8591ffSMauro Carvalho Chehab dev_printk(KERN_DEBUG, &dev->udev->dev, \ 50*ce8591ffSMauro Carvalho Chehab "i2c: %s: " fmt, __func__, ## arg); \ 51*ce8591ffSMauro Carvalho Chehab } while (0) 52*ce8591ffSMauro Carvalho Chehab 53*ce8591ffSMauro Carvalho Chehab 540c0d06caSMauro Carvalho Chehab /* 55f5ae371aSFrank Schaefer * em2800_i2c_send_bytes() 56f5ae371aSFrank Schaefer * send up to 4 bytes to the em2800 i2c device 570c0d06caSMauro Carvalho Chehab */ 58f5ae371aSFrank Schaefer static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 590c0d06caSMauro Carvalho Chehab { 60d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 610c0d06caSMauro Carvalho Chehab int ret; 62a6bad040SFrank Schaefer u8 b2[6]; 63f5ae371aSFrank Schaefer 64f5ae371aSFrank Schaefer if (len < 1 || len > 4) 65f5ae371aSFrank Schaefer return -EOPNOTSUPP; 66f5ae371aSFrank Schaefer 670c0d06caSMauro Carvalho Chehab BUG_ON(len < 1 || len > 4); 680c0d06caSMauro Carvalho Chehab b2[5] = 0x80 + len - 1; 690c0d06caSMauro Carvalho Chehab b2[4] = addr; 700c0d06caSMauro Carvalho Chehab b2[3] = buf[0]; 710c0d06caSMauro Carvalho Chehab if (len > 1) 720c0d06caSMauro Carvalho Chehab b2[2] = buf[1]; 730c0d06caSMauro Carvalho Chehab if (len > 2) 740c0d06caSMauro Carvalho Chehab b2[1] = buf[2]; 750c0d06caSMauro Carvalho Chehab if (len > 3) 760c0d06caSMauro Carvalho Chehab b2[0] = buf[3]; 770c0d06caSMauro Carvalho Chehab 782fcc82d8SFrank Schaefer /* trigger write */ 790c0d06caSMauro Carvalho Chehab ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); 800c0d06caSMauro Carvalho Chehab if (ret != 2 + len) { 81*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 82*ce8591ffSMauro Carvalho Chehab "failed to trigger write to i2c address 0x%x (error=%i)\n", 83d230d5adSFrank Schaefer addr, ret); 8445f04e82SFrank Schaefer return (ret < 0) ? ret : -EIO; 850c0d06caSMauro Carvalho Chehab } 862fcc82d8SFrank Schaefer /* wait for completion */ 874b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 880c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg(dev, 0x05); 894b83626aSMauro Carvalho Chehab if (ret == 0x80 + len - 1) 900c0d06caSMauro Carvalho Chehab return len; 914b83626aSMauro Carvalho Chehab if (ret == 0x94 + len - 1) { 92*ce8591ffSMauro Carvalho Chehab dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", ret); 93e63b009dSMauro Carvalho Chehab return -ENXIO; 944b83626aSMauro Carvalho Chehab } 954b83626aSMauro Carvalho Chehab if (ret < 0) { 96*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 97*ce8591ffSMauro Carvalho Chehab "failed to get i2c transfer status from bridge register (error=%i)\n", 98d230d5adSFrank Schaefer ret); 9945f04e82SFrank Schaefer return ret; 10045f04e82SFrank Schaefer } 1010c0d06caSMauro Carvalho Chehab msleep(5); 1020c0d06caSMauro Carvalho Chehab } 103*ce8591ffSMauro Carvalho Chehab dprintk(0, "write to i2c device at 0x%x timed out\n", addr); 104e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 1050c0d06caSMauro Carvalho Chehab } 1060c0d06caSMauro Carvalho Chehab 1070c0d06caSMauro Carvalho Chehab /* 1080c0d06caSMauro Carvalho Chehab * em2800_i2c_recv_bytes() 1092fcc82d8SFrank Schaefer * read up to 4 bytes from the em2800 i2c device 1100c0d06caSMauro Carvalho Chehab */ 111a6bad040SFrank Schaefer static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len) 1120c0d06caSMauro Carvalho Chehab { 113d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 1142fcc82d8SFrank Schaefer u8 buf2[4]; 1150c0d06caSMauro Carvalho Chehab int ret; 1162fcc82d8SFrank Schaefer int i; 117f5ae371aSFrank Schaefer 118f5ae371aSFrank Schaefer if (len < 1 || len > 4) 119f5ae371aSFrank Schaefer return -EOPNOTSUPP; 120f5ae371aSFrank Schaefer 1212fcc82d8SFrank Schaefer /* trigger read */ 1222fcc82d8SFrank Schaefer buf2[1] = 0x84 + len - 1; 1232fcc82d8SFrank Schaefer buf2[0] = addr; 1242fcc82d8SFrank Schaefer ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2); 1252fcc82d8SFrank Schaefer if (ret != 2) { 126*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 127*ce8591ffSMauro Carvalho Chehab "failed to trigger read from i2c address 0x%x (error=%i)\n", 128d230d5adSFrank Schaefer addr, ret); 1292fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1302fcc82d8SFrank Schaefer } 1312fcc82d8SFrank Schaefer 1322fcc82d8SFrank Schaefer /* wait for completion */ 1334b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 1342fcc82d8SFrank Schaefer ret = dev->em28xx_read_reg(dev, 0x05); 1354b83626aSMauro Carvalho Chehab if (ret == 0x84 + len - 1) 1362fcc82d8SFrank Schaefer break; 1374b83626aSMauro Carvalho Chehab if (ret == 0x94 + len - 1) { 138*ce8591ffSMauro Carvalho Chehab dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", 139d845fb3aSMauro Carvalho Chehab ret); 140e63b009dSMauro Carvalho Chehab return -ENXIO; 1414b83626aSMauro Carvalho Chehab } 1424b83626aSMauro Carvalho Chehab if (ret < 0) { 143*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 144*ce8591ffSMauro Carvalho Chehab "failed to get i2c transfer status from bridge register (error=%i)\n", 145d230d5adSFrank Schaefer ret); 1460c0d06caSMauro Carvalho Chehab return ret; 1470c0d06caSMauro Carvalho Chehab } 1482fcc82d8SFrank Schaefer msleep(5); 1492fcc82d8SFrank Schaefer } 15050f0a9dfSMauro Carvalho Chehab if (ret != 0x84 + len - 1) { 151*ce8591ffSMauro Carvalho Chehab dprintk(0, "read from i2c device at 0x%x timed out\n", addr); 15250f0a9dfSMauro Carvalho Chehab } 1532fcc82d8SFrank Schaefer 1542fcc82d8SFrank Schaefer /* get the received message */ 1552fcc82d8SFrank Schaefer ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len); 1562fcc82d8SFrank Schaefer if (ret != len) { 157*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 158*ce8591ffSMauro Carvalho Chehab "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n", 159d230d5adSFrank Schaefer addr, ret); 1602fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1612fcc82d8SFrank Schaefer } 1622fcc82d8SFrank Schaefer for (i = 0; i < len; i++) 1632fcc82d8SFrank Schaefer buf[i] = buf2[len - 1 - i]; 1642fcc82d8SFrank Schaefer 1650c0d06caSMauro Carvalho Chehab return ret; 1660c0d06caSMauro Carvalho Chehab } 1672fcc82d8SFrank Schaefer 1682fcc82d8SFrank Schaefer /* 1692fcc82d8SFrank Schaefer * em2800_i2c_check_for_device() 1702fcc82d8SFrank Schaefer * check if there is an i2c device at the supplied address 1712fcc82d8SFrank Schaefer */ 1722fcc82d8SFrank Schaefer static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr) 1732fcc82d8SFrank Schaefer { 1742fcc82d8SFrank Schaefer u8 buf; 1752fcc82d8SFrank Schaefer int ret; 1762fcc82d8SFrank Schaefer 1772fcc82d8SFrank Schaefer ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1); 1782fcc82d8SFrank Schaefer if (ret == 1) 1792fcc82d8SFrank Schaefer return 0; 1802fcc82d8SFrank Schaefer return (ret < 0) ? ret : -EIO; 1810c0d06caSMauro Carvalho Chehab } 1820c0d06caSMauro Carvalho Chehab 1830c0d06caSMauro Carvalho Chehab /* 1840c0d06caSMauro Carvalho Chehab * em28xx_i2c_send_bytes() 1850c0d06caSMauro Carvalho Chehab */ 186a6bad040SFrank Schaefer static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, 187a6bad040SFrank Schaefer u16 len, int stop) 1880c0d06caSMauro Carvalho Chehab { 189d1b7213bSMauro Carvalho Chehab unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_I2C_XFER_TIMEOUT); 1904b83626aSMauro Carvalho Chehab int ret; 1910c0d06caSMauro Carvalho Chehab 192f5ae371aSFrank Schaefer if (len < 1 || len > 64) 193f5ae371aSFrank Schaefer return -EOPNOTSUPP; 194fa74aca3SFrank Schaefer /* 195fa74aca3SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 196fa74aca3SFrank Schaefer * Zero length reads always succeed, even if no device is connected 197fa74aca3SFrank Schaefer */ 198f5ae371aSFrank Schaefer 19945f04e82SFrank Schaefer /* Write to i2c device */ 20045f04e82SFrank Schaefer ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); 20145f04e82SFrank Schaefer if (ret != len) { 20245f04e82SFrank Schaefer if (ret < 0) { 203*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 204*ce8591ffSMauro Carvalho Chehab "writing to i2c device at 0x%x failed (error=%i)\n", 205d230d5adSFrank Schaefer addr, ret); 20645f04e82SFrank Schaefer return ret; 20745f04e82SFrank Schaefer } else { 208*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 209*ce8591ffSMauro Carvalho Chehab "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", 21045f04e82SFrank Schaefer len, addr, ret); 21145f04e82SFrank Schaefer return -EIO; 21245f04e82SFrank Schaefer } 21345f04e82SFrank Schaefer } 2140c0d06caSMauro Carvalho Chehab 2154b83626aSMauro Carvalho Chehab /* wait for completion */ 2164b83626aSMauro Carvalho Chehab while (time_is_after_jiffies(timeout)) { 2170c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg(dev, 0x05); 2184b83626aSMauro Carvalho Chehab if (ret == 0) /* success */ 21945f04e82SFrank Schaefer return len; 2204b83626aSMauro Carvalho Chehab if (ret == 0x10) { 221*ce8591ffSMauro Carvalho Chehab dprintk(1, "I2C ACK error on writing to addr 0x%02x\n", 222d845fb3aSMauro Carvalho Chehab addr); 223e63b009dSMauro Carvalho Chehab return -ENXIO; 2244b83626aSMauro Carvalho Chehab } 2254b83626aSMauro Carvalho Chehab if (ret < 0) { 226*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 227*ce8591ffSMauro Carvalho Chehab "failed to get i2c transfer status from bridge register (error=%i)\n", 228d230d5adSFrank Schaefer ret); 22945f04e82SFrank Schaefer return ret; 2300c0d06caSMauro Carvalho Chehab } 23145f04e82SFrank Schaefer msleep(5); 232fa74aca3SFrank Schaefer /* 233fa74aca3SFrank Schaefer * NOTE: do we really have to wait for success ? 234fa74aca3SFrank Schaefer * Never seen anything else than 0x00 or 0x10 235fa74aca3SFrank Schaefer * (even with high payload) ... 236fa74aca3SFrank Schaefer */ 23745f04e82SFrank Schaefer } 238123a17d1SFrank Schaefer 239123a17d1SFrank Schaefer if (ret == 0x02 || ret == 0x04) { 240123a17d1SFrank Schaefer /* NOTE: these errors seem to be related to clock stretching */ 241*ce8591ffSMauro Carvalho Chehab dprintk(0, 242*ce8591ffSMauro Carvalho Chehab "write to i2c device at 0x%x timed out (status=%i)\n", 24350f0a9dfSMauro Carvalho Chehab addr, ret); 244e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 2450c0d06caSMauro Carvalho Chehab } 2460c0d06caSMauro Carvalho Chehab 247*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 248*ce8591ffSMauro Carvalho Chehab "write to i2c device at 0x%x failed with unknown error (status=%i)\n", 249123a17d1SFrank Schaefer addr, ret); 250123a17d1SFrank Schaefer return -EIO; 251123a17d1SFrank Schaefer } 252123a17d1SFrank Schaefer 2530c0d06caSMauro Carvalho Chehab /* 2540c0d06caSMauro Carvalho Chehab * em28xx_i2c_recv_bytes() 2550c0d06caSMauro Carvalho Chehab * read a byte from the i2c device 2560c0d06caSMauro Carvalho Chehab */ 257a6bad040SFrank Schaefer static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len) 2580c0d06caSMauro Carvalho Chehab { 2590c0d06caSMauro Carvalho Chehab int ret; 260f5ae371aSFrank Schaefer 261f5ae371aSFrank Schaefer if (len < 1 || len > 64) 262f5ae371aSFrank Schaefer return -EOPNOTSUPP; 263fa74aca3SFrank Schaefer /* 264fa74aca3SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 265fa74aca3SFrank Schaefer * Zero length reads always succeed, even if no device is connected 266fa74aca3SFrank Schaefer */ 267f5ae371aSFrank Schaefer 26845f04e82SFrank Schaefer /* Read data from i2c device */ 2690c0d06caSMauro Carvalho Chehab ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); 2700c0d06caSMauro Carvalho Chehab if (ret < 0) { 271*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 272*ce8591ffSMauro Carvalho Chehab "reading from i2c device at 0x%x failed (error=%i)\n", 2737f6301d1SFrank Schaefer addr, ret); 27445f04e82SFrank Schaefer return ret; 27545f04e82SFrank Schaefer } 276fa74aca3SFrank Schaefer /* 277fa74aca3SFrank Schaefer * NOTE: some devices with two i2c busses have the bad habit to return 0 2787f6301d1SFrank Schaefer * bytes if we are on bus B AND there was no write attempt to the 2797f6301d1SFrank Schaefer * specified slave address before AND no device is present at the 2807f6301d1SFrank Schaefer * requested slave address. 281e63b009dSMauro Carvalho Chehab * Anyway, the next check will fail with -ENXIO in this case, so avoid 2827f6301d1SFrank Schaefer * spamming the system log on device probing and do nothing here. 2837f6301d1SFrank Schaefer */ 28445f04e82SFrank Schaefer 28545f04e82SFrank Schaefer /* Check success of the i2c operation */ 28645f04e82SFrank Schaefer ret = dev->em28xx_read_reg(dev, 0x05); 2874b83626aSMauro Carvalho Chehab if (ret == 0) /* success */ 2884b83626aSMauro Carvalho Chehab return len; 28945f04e82SFrank Schaefer if (ret < 0) { 290*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 291*ce8591ffSMauro Carvalho Chehab "failed to get i2c transfer status from bridge register (error=%i)\n", 292d230d5adSFrank Schaefer ret); 2930c0d06caSMauro Carvalho Chehab return ret; 2940c0d06caSMauro Carvalho Chehab } 295d845fb3aSMauro Carvalho Chehab if (ret == 0x10) { 296*ce8591ffSMauro Carvalho Chehab dprintk(1, "I2C ACK error on writing to addr 0x%02x\n", 297d845fb3aSMauro Carvalho Chehab addr); 298e63b009dSMauro Carvalho Chehab return -ENXIO; 299d845fb3aSMauro Carvalho Chehab } 3004b83626aSMauro Carvalho Chehab 301123a17d1SFrank Schaefer if (ret == 0x02 || ret == 0x04) { 302123a17d1SFrank Schaefer /* NOTE: these errors seem to be related to clock stretching */ 303*ce8591ffSMauro Carvalho Chehab dprintk(0, 304*ce8591ffSMauro Carvalho Chehab "write to i2c device at 0x%x timed out (status=%i)\n", 305123a17d1SFrank Schaefer addr, ret); 306e63b009dSMauro Carvalho Chehab return -ETIMEDOUT; 30745f04e82SFrank Schaefer } 3080c0d06caSMauro Carvalho Chehab 309*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 310*ce8591ffSMauro Carvalho Chehab "write to i2c device at 0x%x failed with unknown error (status=%i)\n", 311123a17d1SFrank Schaefer addr, ret); 312123a17d1SFrank Schaefer return -EIO; 313123a17d1SFrank Schaefer } 314123a17d1SFrank Schaefer 3150c0d06caSMauro Carvalho Chehab /* 3160c0d06caSMauro Carvalho Chehab * em28xx_i2c_check_for_device() 3170c0d06caSMauro Carvalho Chehab * check if there is a i2c_device at the supplied address 3180c0d06caSMauro Carvalho Chehab */ 319a6bad040SFrank Schaefer static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr) 3200c0d06caSMauro Carvalho Chehab { 3210c0d06caSMauro Carvalho Chehab int ret; 32245f04e82SFrank Schaefer u8 buf; 3230c0d06caSMauro Carvalho Chehab 32445f04e82SFrank Schaefer ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1); 32545f04e82SFrank Schaefer if (ret == 1) 3260c0d06caSMauro Carvalho Chehab return 0; 32745f04e82SFrank Schaefer return (ret < 0) ? ret : -EIO; 3280c0d06caSMauro Carvalho Chehab } 3290c0d06caSMauro Carvalho Chehab 3300c0d06caSMauro Carvalho Chehab /* 331a3ea4bf9SFrank Schaefer * em25xx_bus_B_send_bytes 332a3ea4bf9SFrank Schaefer * write bytes to the i2c device 333a3ea4bf9SFrank Schaefer */ 334a3ea4bf9SFrank Schaefer static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf, 335a3ea4bf9SFrank Schaefer u16 len) 336a3ea4bf9SFrank Schaefer { 337a3ea4bf9SFrank Schaefer int ret; 338a3ea4bf9SFrank Schaefer 339a3ea4bf9SFrank Schaefer if (len < 1 || len > 64) 340a3ea4bf9SFrank Schaefer return -EOPNOTSUPP; 341a3ea4bf9SFrank Schaefer /* 342a3ea4bf9SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 343a3ea4bf9SFrank Schaefer * Zero length reads always succeed, even if no device is connected 344a3ea4bf9SFrank Schaefer */ 345a3ea4bf9SFrank Schaefer 346a3ea4bf9SFrank Schaefer /* Set register and write value */ 347a3ea4bf9SFrank Schaefer ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len); 348a3ea4bf9SFrank Schaefer if (ret != len) { 349a3ea4bf9SFrank Schaefer if (ret < 0) { 350*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 351*ce8591ffSMauro Carvalho Chehab "writing to i2c device at 0x%x failed (error=%i)\n", 352a3ea4bf9SFrank Schaefer addr, ret); 353a3ea4bf9SFrank Schaefer return ret; 354a3ea4bf9SFrank Schaefer } else { 355*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 356*ce8591ffSMauro Carvalho Chehab "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n", 357a3ea4bf9SFrank Schaefer len, addr, ret); 358a3ea4bf9SFrank Schaefer return -EIO; 359a3ea4bf9SFrank Schaefer } 360a3ea4bf9SFrank Schaefer } 361a3ea4bf9SFrank Schaefer /* Check success */ 362a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); 363a3ea4bf9SFrank Schaefer /* 364a3ea4bf9SFrank Schaefer * NOTE: the only error we've seen so far is 365a3ea4bf9SFrank Schaefer * 0x01 when the slave device is not present 366a3ea4bf9SFrank Schaefer */ 367a3ea4bf9SFrank Schaefer if (!ret) 368a3ea4bf9SFrank Schaefer return len; 369d845fb3aSMauro Carvalho Chehab else if (ret > 0) { 370*ce8591ffSMauro Carvalho Chehab dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); 371e63b009dSMauro Carvalho Chehab return -ENXIO; 372d845fb3aSMauro Carvalho Chehab } 373a3ea4bf9SFrank Schaefer 374a3ea4bf9SFrank Schaefer return ret; 375a3ea4bf9SFrank Schaefer /* 376a3ea4bf9SFrank Schaefer * NOTE: With chip types (other chip IDs) which actually don't support 377a3ea4bf9SFrank Schaefer * this operation, it seems to succeed ALWAYS ! (even if there is no 378a3ea4bf9SFrank Schaefer * slave device or even no second i2c bus provided) 379a3ea4bf9SFrank Schaefer */ 380a3ea4bf9SFrank Schaefer } 381a3ea4bf9SFrank Schaefer 382a3ea4bf9SFrank Schaefer /* 383a3ea4bf9SFrank Schaefer * em25xx_bus_B_recv_bytes 384a3ea4bf9SFrank Schaefer * read bytes from the i2c device 385a3ea4bf9SFrank Schaefer */ 386a3ea4bf9SFrank Schaefer static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, 387a3ea4bf9SFrank Schaefer u16 len) 388a3ea4bf9SFrank Schaefer { 389a3ea4bf9SFrank Schaefer int ret; 390a3ea4bf9SFrank Schaefer 391a3ea4bf9SFrank Schaefer if (len < 1 || len > 64) 392a3ea4bf9SFrank Schaefer return -EOPNOTSUPP; 393a3ea4bf9SFrank Schaefer /* 394a3ea4bf9SFrank Schaefer * NOTE: limited by the USB ctrl message constraints 395a3ea4bf9SFrank Schaefer * Zero length reads always succeed, even if no device is connected 396a3ea4bf9SFrank Schaefer */ 397a3ea4bf9SFrank Schaefer 398a3ea4bf9SFrank Schaefer /* Read value */ 399a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len); 400a3ea4bf9SFrank Schaefer if (ret < 0) { 401*ce8591ffSMauro Carvalho Chehab dev_warn(&dev->udev->dev, 402*ce8591ffSMauro Carvalho Chehab "reading from i2c device at 0x%x failed (error=%i)\n", 403a3ea4bf9SFrank Schaefer addr, ret); 404a3ea4bf9SFrank Schaefer return ret; 405a3ea4bf9SFrank Schaefer } 406a3ea4bf9SFrank Schaefer /* 407a3ea4bf9SFrank Schaefer * NOTE: some devices with two i2c busses have the bad habit to return 0 408a3ea4bf9SFrank Schaefer * bytes if we are on bus B AND there was no write attempt to the 409a3ea4bf9SFrank Schaefer * specified slave address before AND no device is present at the 410a3ea4bf9SFrank Schaefer * requested slave address. 411e63b009dSMauro Carvalho Chehab * Anyway, the next check will fail with -ENXIO in this case, so avoid 412a3ea4bf9SFrank Schaefer * spamming the system log on device probing and do nothing here. 413a3ea4bf9SFrank Schaefer */ 414a3ea4bf9SFrank Schaefer 415a3ea4bf9SFrank Schaefer /* Check success */ 416a3ea4bf9SFrank Schaefer ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000); 417a3ea4bf9SFrank Schaefer /* 418a3ea4bf9SFrank Schaefer * NOTE: the only error we've seen so far is 419a3ea4bf9SFrank Schaefer * 0x01 when the slave device is not present 420a3ea4bf9SFrank Schaefer */ 421a3ea4bf9SFrank Schaefer if (!ret) 422a3ea4bf9SFrank Schaefer return len; 423d845fb3aSMauro Carvalho Chehab else if (ret > 0) { 424*ce8591ffSMauro Carvalho Chehab dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret); 425e63b009dSMauro Carvalho Chehab return -ENXIO; 426d845fb3aSMauro Carvalho Chehab } 427a3ea4bf9SFrank Schaefer 428a3ea4bf9SFrank Schaefer return ret; 429a3ea4bf9SFrank Schaefer /* 430a3ea4bf9SFrank Schaefer * NOTE: With chip types (other chip IDs) which actually don't support 431a3ea4bf9SFrank Schaefer * this operation, it seems to succeed ALWAYS ! (even if there is no 432a3ea4bf9SFrank Schaefer * slave device or even no second i2c bus provided) 433a3ea4bf9SFrank Schaefer */ 434a3ea4bf9SFrank Schaefer } 435a3ea4bf9SFrank Schaefer 436a3ea4bf9SFrank Schaefer /* 437a3ea4bf9SFrank Schaefer * em25xx_bus_B_check_for_device() 438a3ea4bf9SFrank Schaefer * check if there is a i2c device at the supplied address 439a3ea4bf9SFrank Schaefer */ 440a3ea4bf9SFrank Schaefer static int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr) 441a3ea4bf9SFrank Schaefer { 442a3ea4bf9SFrank Schaefer u8 buf; 443a3ea4bf9SFrank Schaefer int ret; 444a3ea4bf9SFrank Schaefer 445a3ea4bf9SFrank Schaefer ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1); 446a3ea4bf9SFrank Schaefer if (ret < 0) 447a3ea4bf9SFrank Schaefer return ret; 448a3ea4bf9SFrank Schaefer 449a3ea4bf9SFrank Schaefer return 0; 450a3ea4bf9SFrank Schaefer /* 451a3ea4bf9SFrank Schaefer * NOTE: With chips which do not support this operation, 452a3ea4bf9SFrank Schaefer * it seems to succeed ALWAYS ! (even if no device connected) 453a3ea4bf9SFrank Schaefer */ 454a3ea4bf9SFrank Schaefer } 455a3ea4bf9SFrank Schaefer 456a3ea4bf9SFrank Schaefer static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr) 457a3ea4bf9SFrank Schaefer { 458a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 459a3ea4bf9SFrank Schaefer int rc = -EOPNOTSUPP; 460a3ea4bf9SFrank Schaefer 461a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 462a3ea4bf9SFrank Schaefer rc = em28xx_i2c_check_for_device(dev, addr); 463a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 464a3ea4bf9SFrank Schaefer rc = em2800_i2c_check_for_device(dev, addr); 465a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 466a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_check_for_device(dev, addr); 467a3ea4bf9SFrank Schaefer return rc; 468a3ea4bf9SFrank Schaefer } 469a3ea4bf9SFrank Schaefer 470a3ea4bf9SFrank Schaefer static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus, 471a3ea4bf9SFrank Schaefer struct i2c_msg msg) 472a3ea4bf9SFrank Schaefer { 473a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 474a3ea4bf9SFrank Schaefer u16 addr = msg.addr << 1; 47550f0a9dfSMauro Carvalho Chehab int rc = -EOPNOTSUPP; 476a3ea4bf9SFrank Schaefer 477a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 478a3ea4bf9SFrank Schaefer rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 479a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 480a3ea4bf9SFrank Schaefer rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len); 481a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 482a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len); 483a3ea4bf9SFrank Schaefer return rc; 484a3ea4bf9SFrank Schaefer } 485a3ea4bf9SFrank Schaefer 486a3ea4bf9SFrank Schaefer static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus, 487a3ea4bf9SFrank Schaefer struct i2c_msg msg, int stop) 488a3ea4bf9SFrank Schaefer { 489a3ea4bf9SFrank Schaefer struct em28xx *dev = i2c_bus->dev; 490a3ea4bf9SFrank Schaefer u16 addr = msg.addr << 1; 49150f0a9dfSMauro Carvalho Chehab int rc = -EOPNOTSUPP; 492a3ea4bf9SFrank Schaefer 493a3ea4bf9SFrank Schaefer if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) 494a3ea4bf9SFrank Schaefer rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop); 495a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) 496a3ea4bf9SFrank Schaefer rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len); 497a3ea4bf9SFrank Schaefer else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B) 498a3ea4bf9SFrank Schaefer rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len); 499a3ea4bf9SFrank Schaefer return rc; 500a3ea4bf9SFrank Schaefer } 501a3ea4bf9SFrank Schaefer 502a3ea4bf9SFrank Schaefer /* 5030c0d06caSMauro Carvalho Chehab * em28xx_i2c_xfer() 5040c0d06caSMauro Carvalho Chehab * the main i2c transfer function 5050c0d06caSMauro Carvalho Chehab */ 5060c0d06caSMauro Carvalho Chehab static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, 5070c0d06caSMauro Carvalho Chehab struct i2c_msg msgs[], int num) 5080c0d06caSMauro Carvalho Chehab { 509aab3125cSMauro Carvalho Chehab struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 510aab3125cSMauro Carvalho Chehab struct em28xx *dev = i2c_bus->dev; 511aab3125cSMauro Carvalho Chehab unsigned bus = i2c_bus->bus; 512a3ea4bf9SFrank Schaefer int addr, rc, i; 5133190fbeeSMauro Carvalho Chehab u8 reg; 5140c0d06caSMauro Carvalho Chehab 515cc5c5d20SShuah Khan /* prevent i2c xfer attempts after device is disconnected 516cc5c5d20SShuah Khan some fe's try to do i2c writes/reads from their release 517cc5c5d20SShuah Khan interfaces when called in disconnect path */ 518cc5c5d20SShuah Khan if (dev->disconnected) 519cc5c5d20SShuah Khan return -ENODEV; 520cc5c5d20SShuah Khan 521e44c153bSDan Carpenter if (!rt_mutex_trylock(&dev->i2c_bus_lock)) 522e44c153bSDan Carpenter return -EAGAIN; 523aab3125cSMauro Carvalho Chehab 524aab3125cSMauro Carvalho Chehab /* Switch I2C bus if needed */ 525a3ea4bf9SFrank Schaefer if (bus != dev->cur_i2c_bus && 526a3ea4bf9SFrank Schaefer i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) { 527aab3125cSMauro Carvalho Chehab if (bus == 1) 5283190fbeeSMauro Carvalho Chehab reg = EM2874_I2C_SECONDARY_BUS_SELECT; 529aab3125cSMauro Carvalho Chehab else 5303190fbeeSMauro Carvalho Chehab reg = 0; 5313190fbeeSMauro Carvalho Chehab em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg, 5323190fbeeSMauro Carvalho Chehab EM2874_I2C_SECONDARY_BUS_SELECT); 533aab3125cSMauro Carvalho Chehab dev->cur_i2c_bus = bus; 534aab3125cSMauro Carvalho Chehab } 535aab3125cSMauro Carvalho Chehab 536aab3125cSMauro Carvalho Chehab if (num <= 0) { 537aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 5380c0d06caSMauro Carvalho Chehab return 0; 539aab3125cSMauro Carvalho Chehab } 5400c0d06caSMauro Carvalho Chehab for (i = 0; i < num; i++) { 5410c0d06caSMauro Carvalho Chehab addr = msgs[i].addr << 1; 542e63b009dSMauro Carvalho Chehab if (!msgs[i].len) { 543e63b009dSMauro Carvalho Chehab /* 544e63b009dSMauro Carvalho Chehab * no len: check only for device presence 545e63b009dSMauro Carvalho Chehab * This code is only called during device probe. 546e63b009dSMauro Carvalho Chehab */ 547a3ea4bf9SFrank Schaefer rc = i2c_check_for_device(i2c_bus, addr); 548*ce8591ffSMauro Carvalho Chehab 549*ce8591ffSMauro Carvalho Chehab if (rc == -ENXIO) 55050f0a9dfSMauro Carvalho Chehab rc = -ENODEV; 5510c0d06caSMauro Carvalho Chehab } else if (msgs[i].flags & I2C_M_RD) { 5520c0d06caSMauro Carvalho Chehab /* read bytes */ 553a3ea4bf9SFrank Schaefer rc = i2c_recv_bytes(i2c_bus, msgs[i]); 5540c0d06caSMauro Carvalho Chehab } else { 5550c0d06caSMauro Carvalho Chehab /* write bytes */ 556a3ea4bf9SFrank Schaefer rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1); 5570c0d06caSMauro Carvalho Chehab } 558*ce8591ffSMauro Carvalho Chehab 559*ce8591ffSMauro Carvalho Chehab if (rc < 0) 560*ce8591ffSMauro Carvalho Chehab goto error; 561*ce8591ffSMauro Carvalho Chehab 562*ce8591ffSMauro Carvalho Chehab dprintk(2, "%s %s addr=%02x len=%d: %*ph\n", 563*ce8591ffSMauro Carvalho Chehab (msgs[i].flags & I2C_M_RD) ? "read" : "write", 564*ce8591ffSMauro Carvalho Chehab i == num - 1 ? "stop" : "nonstop", 565*ce8591ffSMauro Carvalho Chehab addr, msgs[i].len, 566*ce8591ffSMauro Carvalho Chehab msgs[i].len, msgs[i].buf); 5670c0d06caSMauro Carvalho Chehab } 5680c0d06caSMauro Carvalho Chehab 569aab3125cSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 5700c0d06caSMauro Carvalho Chehab return num; 571*ce8591ffSMauro Carvalho Chehab 572*ce8591ffSMauro Carvalho Chehab error: 573*ce8591ffSMauro Carvalho Chehab dprintk(2, "%s %s addr=%02x len=%d: %sERROR: %i\n", 574*ce8591ffSMauro Carvalho Chehab (msgs[i].flags & I2C_M_RD) ? "read" : "write", 575*ce8591ffSMauro Carvalho Chehab i == num - 1 ? "stop" : "nonstop", 576*ce8591ffSMauro Carvalho Chehab addr, msgs[i].len, 577*ce8591ffSMauro Carvalho Chehab (rc == -ENODEV) ? "no device " : "", 578*ce8591ffSMauro Carvalho Chehab rc); 579*ce8591ffSMauro Carvalho Chehab 580*ce8591ffSMauro Carvalho Chehab rt_mutex_unlock(&dev->i2c_bus_lock); 581*ce8591ffSMauro Carvalho Chehab return rc; 5820c0d06caSMauro Carvalho Chehab } 5830c0d06caSMauro Carvalho Chehab 584fa74aca3SFrank Schaefer /* 585fa74aca3SFrank Schaefer * based on linux/sunrpc/svcauth.h and linux/hash.h 5860c0d06caSMauro Carvalho Chehab * The original hash function returns a different value, if arch is x86_64 5870c0d06caSMauro Carvalho Chehab * or i386. 5880c0d06caSMauro Carvalho Chehab */ 5890c0d06caSMauro Carvalho Chehab static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) 5900c0d06caSMauro Carvalho Chehab { 5910c0d06caSMauro Carvalho Chehab unsigned long hash = 0; 5920c0d06caSMauro Carvalho Chehab unsigned long l = 0; 5930c0d06caSMauro Carvalho Chehab int len = 0; 5940c0d06caSMauro Carvalho Chehab unsigned char c; 595fdf1bc9fSMauro Carvalho Chehab 5960c0d06caSMauro Carvalho Chehab do { 5970c0d06caSMauro Carvalho Chehab if (len == length) { 5980c0d06caSMauro Carvalho Chehab c = (char)len; 5990c0d06caSMauro Carvalho Chehab len = -1; 6000c0d06caSMauro Carvalho Chehab } else 6010c0d06caSMauro Carvalho Chehab c = *buf++; 6020c0d06caSMauro Carvalho Chehab l = (l << 8) | c; 6030c0d06caSMauro Carvalho Chehab len++; 6040c0d06caSMauro Carvalho Chehab if ((len & (32 / 8 - 1)) == 0) 6050c0d06caSMauro Carvalho Chehab hash = ((hash^l) * 0x9e370001UL); 6060c0d06caSMauro Carvalho Chehab } while (len); 6070c0d06caSMauro Carvalho Chehab 6080c0d06caSMauro Carvalho Chehab return (hash >> (32 - bits)) & 0xffffffffUL; 6090c0d06caSMauro Carvalho Chehab } 6100c0d06caSMauro Carvalho Chehab 611fa74aca3SFrank Schaefer /* 612fa74aca3SFrank Schaefer * Helper function to read data blocks from i2c clients with 8 or 16 bit 613fa74aca3SFrank Schaefer * address width, 8 bit register width and auto incrementation been activated 614fa74aca3SFrank Schaefer */ 615aab3125cSMauro Carvalho Chehab static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr, 616aab3125cSMauro Carvalho Chehab bool addr_w16, u16 len, u8 *data) 617d832c5b2SFrank Schaefer { 618d832c5b2SFrank Schaefer int remain = len, rsize, rsize_max, ret; 619d832c5b2SFrank Schaefer u8 buf[2]; 620d832c5b2SFrank Schaefer 621d832c5b2SFrank Schaefer /* Sanity check */ 622d832c5b2SFrank Schaefer if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1)) 623d832c5b2SFrank Schaefer return -EINVAL; 624d832c5b2SFrank Schaefer /* Select address */ 625d832c5b2SFrank Schaefer buf[0] = addr >> 8; 626d832c5b2SFrank Schaefer buf[1] = addr & 0xff; 627aab3125cSMauro Carvalho Chehab ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16); 628d832c5b2SFrank Schaefer if (ret < 0) 629d832c5b2SFrank Schaefer return ret; 630d832c5b2SFrank Schaefer /* Read data */ 631d832c5b2SFrank Schaefer if (dev->board.is_em2800) 632d832c5b2SFrank Schaefer rsize_max = 4; 633d832c5b2SFrank Schaefer else 634d832c5b2SFrank Schaefer rsize_max = 64; 635d832c5b2SFrank Schaefer while (remain > 0) { 636d832c5b2SFrank Schaefer if (remain > rsize_max) 637d832c5b2SFrank Schaefer rsize = rsize_max; 638d832c5b2SFrank Schaefer else 639d832c5b2SFrank Schaefer rsize = remain; 640d832c5b2SFrank Schaefer 641aab3125cSMauro Carvalho Chehab ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize); 642d832c5b2SFrank Schaefer if (ret < 0) 643d832c5b2SFrank Schaefer return ret; 644d832c5b2SFrank Schaefer 645d832c5b2SFrank Schaefer remain -= rsize; 646d832c5b2SFrank Schaefer data += rsize; 647d832c5b2SFrank Schaefer } 648d832c5b2SFrank Schaefer 649d832c5b2SFrank Schaefer return len; 650d832c5b2SFrank Schaefer } 651d832c5b2SFrank Schaefer 652aab3125cSMauro Carvalho Chehab static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus, 653aab3125cSMauro Carvalho Chehab u8 **eedata, u16 *eedata_len) 6540c0d06caSMauro Carvalho Chehab { 655510e884cSFrank Schaefer const u16 len = 256; 656fa74aca3SFrank Schaefer /* 657fa74aca3SFrank Schaefer * FIXME common length/size for bytes to read, to display, hash 658510e884cSFrank Schaefer * calculation and returned device dataset. Simplifies the code a lot, 659fa74aca3SFrank Schaefer * but we might have to deal with multiple sizes in the future ! 660fa74aca3SFrank Schaefer */ 66150f0a9dfSMauro Carvalho Chehab int err; 662510e884cSFrank Schaefer struct em28xx_eeprom *dev_config; 663510e884cSFrank Schaefer u8 buf, *data; 6640c0d06caSMauro Carvalho Chehab 665a217968fSFrank Schaefer *eedata = NULL; 666510e884cSFrank Schaefer *eedata_len = 0; 667a217968fSFrank Schaefer 668aab3125cSMauro Carvalho Chehab /* EEPROM is always on i2c bus 0 on all known devices. */ 669aab3125cSMauro Carvalho Chehab 670aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].addr = 0xa0 >> 1; 6710c0d06caSMauro Carvalho Chehab 6720c0d06caSMauro Carvalho Chehab /* Check if board has eeprom */ 673aab3125cSMauro Carvalho Chehab err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); 6740c0d06caSMauro Carvalho Chehab if (err < 0) { 675*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "board has no eeprom\n"); 6760c0d06caSMauro Carvalho Chehab return -ENODEV; 6770c0d06caSMauro Carvalho Chehab } 6780c0d06caSMauro Carvalho Chehab 679a217968fSFrank Schaefer data = kzalloc(len, GFP_KERNEL); 680a217968fSFrank Schaefer if (data == NULL) 681a217968fSFrank Schaefer return -ENOMEM; 682a217968fSFrank Schaefer 683d832c5b2SFrank Schaefer /* Read EEPROM content */ 684aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, 0x0000, 685aab3125cSMauro Carvalho Chehab dev->eeprom_addrwidth_16bit, 686a217968fSFrank Schaefer len, data); 687d832c5b2SFrank Schaefer if (err != len) { 688*ce8591ffSMauro Carvalho Chehab dev_err(&dev->udev->dev, 689*ce8591ffSMauro Carvalho Chehab "failed to read eeprom (err=%d)\n", err); 690510e884cSFrank Schaefer goto error; 6910c0d06caSMauro Carvalho Chehab } 69290271964SFrank Schaefer 69350f0a9dfSMauro Carvalho Chehab if (i2c_debug) { 69487b52439SFrank Schaefer /* Display eeprom content */ 695*ce8591ffSMauro Carvalho Chehab print_hex_dump(KERN_DEBUG, "em28xx eeprom ", DUMP_PREFIX_OFFSET, 69650f0a9dfSMauro Carvalho Chehab 16, 1, data, len, true); 69750f0a9dfSMauro Carvalho Chehab 69887b52439SFrank Schaefer if (dev->eeprom_addrwidth_16bit) 699*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 700*ce8591ffSMauro Carvalho Chehab "eeprom %06x: ... (skipped)\n", 256); 70187b52439SFrank Schaefer } 7020c0d06caSMauro Carvalho Chehab 70387b52439SFrank Schaefer if (dev->eeprom_addrwidth_16bit && 704a217968fSFrank Schaefer data[0] == 0x26 && data[3] == 0x00) { 70587b52439SFrank Schaefer /* new eeprom format; size 4-64kb */ 706510e884cSFrank Schaefer u16 mc_start; 707510e884cSFrank Schaefer u16 hwconf_offset; 708510e884cSFrank Schaefer 709a217968fSFrank Schaefer dev->hash = em28xx_hash_mem(data, len, 32); 710510e884cSFrank Schaefer mc_start = (data[1] << 8) + 4; /* usually 0x0004 */ 711510e884cSFrank Schaefer 712*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 713*ce8591ffSMauro Carvalho Chehab "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", 714510e884cSFrank Schaefer data[0], data[1], data[2], data[3], dev->hash); 715*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 716*ce8591ffSMauro Carvalho Chehab "EEPROM info:\n"); 717*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 718*ce8591ffSMauro Carvalho Chehab "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n", 719510e884cSFrank Schaefer mc_start, data[2]); 720fa74aca3SFrank Schaefer /* 721fa74aca3SFrank Schaefer * boot configuration (address 0x0002): 72287b52439SFrank Schaefer * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz 72387b52439SFrank Schaefer * [1] always selects 12 kb RAM 72487b52439SFrank Schaefer * [2] USB device speed: 1 = force Full Speed; 0 = auto detect 72587b52439SFrank Schaefer * [4] 1 = force fast mode and no suspend for device testing 72687b52439SFrank Schaefer * [5:7] USB PHY tuning registers; determined by device 72787b52439SFrank Schaefer * characterization 72887b52439SFrank Schaefer */ 72987b52439SFrank Schaefer 730fa74aca3SFrank Schaefer /* 731fa74aca3SFrank Schaefer * Read hardware config dataset offset from address 732fa74aca3SFrank Schaefer * (microcode start + 46) 733fa74aca3SFrank Schaefer */ 734aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2, 735aab3125cSMauro Carvalho Chehab data); 736510e884cSFrank Schaefer if (err != 2) { 737*ce8591ffSMauro Carvalho Chehab dev_err(&dev->udev->dev, 738*ce8591ffSMauro Carvalho Chehab "failed to read hardware configuration data from eeprom (err=%d)\n", 739510e884cSFrank Schaefer err); 740510e884cSFrank Schaefer goto error; 741510e884cSFrank Schaefer } 74287b52439SFrank Schaefer 743510e884cSFrank Schaefer /* Calculate hardware config dataset start address */ 744510e884cSFrank Schaefer hwconf_offset = mc_start + data[0] + (data[1] << 8); 745510e884cSFrank Schaefer 746510e884cSFrank Schaefer /* Read hardware config dataset */ 747fa74aca3SFrank Schaefer /* 748fa74aca3SFrank Schaefer * NOTE: the microcode copy can be multiple pages long, but 749510e884cSFrank Schaefer * we assume the hardware config dataset is the same as in 750510e884cSFrank Schaefer * the old eeprom and not longer than 256 bytes. 751510e884cSFrank Schaefer * tveeprom is currently also limited to 256 bytes. 752510e884cSFrank Schaefer */ 753aab3125cSMauro Carvalho Chehab err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len, 754aab3125cSMauro Carvalho Chehab data); 755510e884cSFrank Schaefer if (err != len) { 756*ce8591ffSMauro Carvalho Chehab dev_err(&dev->udev->dev, 757*ce8591ffSMauro Carvalho Chehab "failed to read hardware configuration data from eeprom (err=%d)\n", 758510e884cSFrank Schaefer err); 759510e884cSFrank Schaefer goto error; 760510e884cSFrank Schaefer } 761510e884cSFrank Schaefer 762510e884cSFrank Schaefer /* Verify hardware config dataset */ 763510e884cSFrank Schaefer /* NOTE: not all devices provide this type of dataset */ 764510e884cSFrank Schaefer if (data[0] != 0x1a || data[1] != 0xeb || 765a217968fSFrank Schaefer data[2] != 0x67 || data[3] != 0x95) { 766*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 767*ce8591ffSMauro Carvalho Chehab "\tno hardware configuration dataset found in eeprom\n"); 768510e884cSFrank Schaefer kfree(data); 769510e884cSFrank Schaefer return 0; 770510e884cSFrank Schaefer } 771510e884cSFrank Schaefer 772510e884cSFrank Schaefer /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */ 773510e884cSFrank Schaefer 774510e884cSFrank Schaefer } else if (!dev->eeprom_addrwidth_16bit && 775510e884cSFrank Schaefer data[0] == 0x1a && data[1] == 0xeb && 776510e884cSFrank Schaefer data[2] == 0x67 && data[3] == 0x95) { 777510e884cSFrank Schaefer dev->hash = em28xx_hash_mem(data, len, 32); 778*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 779*ce8591ffSMauro Carvalho Chehab "EEPROM ID = %02x %02x %02x %02x, EEPROM hash = 0x%08lx\n", 780510e884cSFrank Schaefer data[0], data[1], data[2], data[3], dev->hash); 781*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 782*ce8591ffSMauro Carvalho Chehab "EEPROM info:\n"); 783510e884cSFrank Schaefer } else { 784*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 785*ce8591ffSMauro Carvalho Chehab "unknown eeprom format or eeprom corrupted !\n"); 786510e884cSFrank Schaefer err = -ENODEV; 787510e884cSFrank Schaefer goto error; 788f55eacbeSFrank Schaefer } 789f55eacbeSFrank Schaefer 790a217968fSFrank Schaefer *eedata = data; 791510e884cSFrank Schaefer *eedata_len = len; 79232bf7c6cSAlban Browaeys dev_config = (void *)*eedata; 793a217968fSFrank Schaefer 794510e884cSFrank Schaefer switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) { 7950c0d06caSMauro Carvalho Chehab case 0: 796*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\tNo audio on board.\n"); 7970c0d06caSMauro Carvalho Chehab break; 7980c0d06caSMauro Carvalho Chehab case 1: 799*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\tAC97 audio (5 sample rates)\n"); 8000c0d06caSMauro Carvalho Chehab break; 8010c0d06caSMauro Carvalho Chehab case 2: 802687ff8b0SFrank Schaefer if (dev->chip_id < CHIP_ID_EM2860) 803*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 804*ce8591ffSMauro Carvalho Chehab "\tI2S audio, sample rate=32k\n"); 805687ff8b0SFrank Schaefer else 806*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 807*ce8591ffSMauro Carvalho Chehab "\tI2S audio, 3 sample rates\n"); 8080c0d06caSMauro Carvalho Chehab break; 8090c0d06caSMauro Carvalho Chehab case 3: 810687ff8b0SFrank Schaefer if (dev->chip_id < CHIP_ID_EM2860) 811*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 812*ce8591ffSMauro Carvalho Chehab "\tI2S audio, 3 sample rates\n"); 813687ff8b0SFrank Schaefer else 814*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 815*ce8591ffSMauro Carvalho Chehab "\tI2S audio, 5 sample rates\n"); 8160c0d06caSMauro Carvalho Chehab break; 8170c0d06caSMauro Carvalho Chehab } 8180c0d06caSMauro Carvalho Chehab 819510e884cSFrank Schaefer if (le16_to_cpu(dev_config->chip_conf) & 1 << 3) 820*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\tUSB Remote wakeup capable\n"); 8210c0d06caSMauro Carvalho Chehab 822510e884cSFrank Schaefer if (le16_to_cpu(dev_config->chip_conf) & 1 << 2) 823*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\tUSB Self power capable\n"); 8240c0d06caSMauro Carvalho Chehab 825510e884cSFrank Schaefer switch (le16_to_cpu(dev_config->chip_conf) & 0x3) { 8260c0d06caSMauro Carvalho Chehab case 0: 827*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\t500mA max power\n"); 8280c0d06caSMauro Carvalho Chehab break; 8290c0d06caSMauro Carvalho Chehab case 1: 830*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\t400mA max power\n"); 8310c0d06caSMauro Carvalho Chehab break; 8320c0d06caSMauro Carvalho Chehab case 2: 833*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\t300mA max power\n"); 8340c0d06caSMauro Carvalho Chehab break; 8350c0d06caSMauro Carvalho Chehab case 3: 836*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, "\t200mA max power\n"); 8370c0d06caSMauro Carvalho Chehab break; 8380c0d06caSMauro Carvalho Chehab } 839*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 840*ce8591ffSMauro Carvalho Chehab "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", 841510e884cSFrank Schaefer dev_config->string_idx_table, 842510e884cSFrank Schaefer le16_to_cpu(dev_config->string1), 843510e884cSFrank Schaefer le16_to_cpu(dev_config->string2), 844510e884cSFrank Schaefer le16_to_cpu(dev_config->string3)); 8450c0d06caSMauro Carvalho Chehab 8460c0d06caSMauro Carvalho Chehab return 0; 847510e884cSFrank Schaefer 848510e884cSFrank Schaefer error: 849510e884cSFrank Schaefer kfree(data); 850510e884cSFrank Schaefer return err; 8510c0d06caSMauro Carvalho Chehab } 8520c0d06caSMauro Carvalho Chehab 8530c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 8540c0d06caSMauro Carvalho Chehab 8550c0d06caSMauro Carvalho Chehab /* 8560c0d06caSMauro Carvalho Chehab * functionality() 8570c0d06caSMauro Carvalho Chehab */ 858aab3125cSMauro Carvalho Chehab static u32 functionality(struct i2c_adapter *i2c_adap) 8590c0d06caSMauro Carvalho Chehab { 860aab3125cSMauro Carvalho Chehab struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 861aab3125cSMauro Carvalho Chehab 862a3ea4bf9SFrank Schaefer if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) || 863a3ea4bf9SFrank Schaefer (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) { 864a3ea4bf9SFrank Schaefer return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 865a3ea4bf9SFrank Schaefer } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) { 866a3ea4bf9SFrank Schaefer return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & 867a3ea4bf9SFrank Schaefer ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; 868a3ea4bf9SFrank Schaefer } 869a3ea4bf9SFrank Schaefer 870a3ea4bf9SFrank Schaefer WARN(1, "Unknown i2c bus algorithm.\n"); 871a3ea4bf9SFrank Schaefer return 0; 8720c0d06caSMauro Carvalho Chehab } 8730c0d06caSMauro Carvalho Chehab 87478f2c50bSJulia Lawall static const struct i2c_algorithm em28xx_algo = { 8750c0d06caSMauro Carvalho Chehab .master_xfer = em28xx_i2c_xfer, 8760c0d06caSMauro Carvalho Chehab .functionality = functionality, 8770c0d06caSMauro Carvalho Chehab }; 8780c0d06caSMauro Carvalho Chehab 8790c0d06caSMauro Carvalho Chehab static struct i2c_adapter em28xx_adap_template = { 8800c0d06caSMauro Carvalho Chehab .owner = THIS_MODULE, 8810c0d06caSMauro Carvalho Chehab .name = "em28xx", 8820c0d06caSMauro Carvalho Chehab .algo = &em28xx_algo, 8830c0d06caSMauro Carvalho Chehab }; 8840c0d06caSMauro Carvalho Chehab 8850c0d06caSMauro Carvalho Chehab static struct i2c_client em28xx_client_template = { 8860c0d06caSMauro Carvalho Chehab .name = "em28xx internal", 8870c0d06caSMauro Carvalho Chehab }; 8880c0d06caSMauro Carvalho Chehab 8890c0d06caSMauro Carvalho Chehab /* ----------------------------------------------------------- */ 8900c0d06caSMauro Carvalho Chehab 8910c0d06caSMauro Carvalho Chehab /* 8920c0d06caSMauro Carvalho Chehab * i2c_devs 8930c0d06caSMauro Carvalho Chehab * incomplete list of known devices 8940c0d06caSMauro Carvalho Chehab */ 8950c0d06caSMauro Carvalho Chehab static char *i2c_devs[128] = { 8969aa785b1SWilson Michaels [0x1c >> 1] = "lgdt330x", 8970b3966e4SFrank Schaefer [0x3e >> 1] = "remote IR sensor", 8980c0d06caSMauro Carvalho Chehab [0x4a >> 1] = "saa7113h", 8990c0d06caSMauro Carvalho Chehab [0x52 >> 1] = "drxk", 9000c0d06caSMauro Carvalho Chehab [0x60 >> 1] = "remote IR sensor", 9010c0d06caSMauro Carvalho Chehab [0x8e >> 1] = "remote IR sensor", 9020c0d06caSMauro Carvalho Chehab [0x86 >> 1] = "tda9887", 9030c0d06caSMauro Carvalho Chehab [0x80 >> 1] = "msp34xx", 9040c0d06caSMauro Carvalho Chehab [0x88 >> 1] = "msp34xx", 9050c0d06caSMauro Carvalho Chehab [0xa0 >> 1] = "eeprom", 9060c0d06caSMauro Carvalho Chehab [0xb0 >> 1] = "tda9874", 9070c0d06caSMauro Carvalho Chehab [0xb8 >> 1] = "tvp5150a", 9080c0d06caSMauro Carvalho Chehab [0xba >> 1] = "webcam sensor or tvp5150a", 9090c0d06caSMauro Carvalho Chehab [0xc0 >> 1] = "tuner (analog)", 9100c0d06caSMauro Carvalho Chehab [0xc2 >> 1] = "tuner (analog)", 9110c0d06caSMauro Carvalho Chehab [0xc4 >> 1] = "tuner (analog)", 9120c0d06caSMauro Carvalho Chehab [0xc6 >> 1] = "tuner (analog)", 9130c0d06caSMauro Carvalho Chehab }; 9140c0d06caSMauro Carvalho Chehab 9150c0d06caSMauro Carvalho Chehab /* 9160c0d06caSMauro Carvalho Chehab * do_i2c_scan() 9170c0d06caSMauro Carvalho Chehab * check i2c address range for devices 9180c0d06caSMauro Carvalho Chehab */ 919aab3125cSMauro Carvalho Chehab void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus) 9200c0d06caSMauro Carvalho Chehab { 9210c0d06caSMauro Carvalho Chehab u8 i2c_devicelist[128]; 9220c0d06caSMauro Carvalho Chehab unsigned char buf; 9230c0d06caSMauro Carvalho Chehab int i, rc; 9240c0d06caSMauro Carvalho Chehab 9250c0d06caSMauro Carvalho Chehab memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); 9260c0d06caSMauro Carvalho Chehab 9270c0d06caSMauro Carvalho Chehab for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { 928aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].addr = i; 929aab3125cSMauro Carvalho Chehab rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0); 9300c0d06caSMauro Carvalho Chehab if (rc < 0) 9310c0d06caSMauro Carvalho Chehab continue; 9320c0d06caSMauro Carvalho Chehab i2c_devicelist[i] = i; 933*ce8591ffSMauro Carvalho Chehab dev_info(&dev->udev->dev, 934*ce8591ffSMauro Carvalho Chehab "found i2c device @ 0x%x on bus %d [%s]\n", 935aab3125cSMauro Carvalho Chehab i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???"); 9360c0d06caSMauro Carvalho Chehab } 9370c0d06caSMauro Carvalho Chehab 938aab3125cSMauro Carvalho Chehab if (bus == dev->def_i2c_bus) 9390c0d06caSMauro Carvalho Chehab dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, 9400c0d06caSMauro Carvalho Chehab ARRAY_SIZE(i2c_devicelist), 32); 9410c0d06caSMauro Carvalho Chehab } 9420c0d06caSMauro Carvalho Chehab 9430c0d06caSMauro Carvalho Chehab /* 9440c0d06caSMauro Carvalho Chehab * em28xx_i2c_register() 9450c0d06caSMauro Carvalho Chehab * register i2c bus 9460c0d06caSMauro Carvalho Chehab */ 947a3ea4bf9SFrank Schaefer int em28xx_i2c_register(struct em28xx *dev, unsigned bus, 948a3ea4bf9SFrank Schaefer enum em28xx_i2c_algo_type algo_type) 9490c0d06caSMauro Carvalho Chehab { 9500c0d06caSMauro Carvalho Chehab int retval; 9510c0d06caSMauro Carvalho Chehab 9520c0d06caSMauro Carvalho Chehab BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); 9530c0d06caSMauro Carvalho Chehab BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); 9540c0d06caSMauro Carvalho Chehab 955aab3125cSMauro Carvalho Chehab if (bus >= NUM_I2C_BUSES) 956aab3125cSMauro Carvalho Chehab return -ENODEV; 957aab3125cSMauro Carvalho Chehab 958aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus] = em28xx_adap_template; 959aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus].dev.parent = &dev->udev->dev; 960*ce8591ffSMauro Carvalho Chehab strcpy(dev->i2c_adap[bus].name, dev_name(&dev->udev->dev)); 961aab3125cSMauro Carvalho Chehab 962aab3125cSMauro Carvalho Chehab dev->i2c_bus[bus].bus = bus; 963a3ea4bf9SFrank Schaefer dev->i2c_bus[bus].algo_type = algo_type; 964aab3125cSMauro Carvalho Chehab dev->i2c_bus[bus].dev = dev; 965aab3125cSMauro Carvalho Chehab dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; 966aab3125cSMauro Carvalho Chehab 967aab3125cSMauro Carvalho Chehab retval = i2c_add_adapter(&dev->i2c_adap[bus]); 9680c0d06caSMauro Carvalho Chehab if (retval < 0) { 969*ce8591ffSMauro Carvalho Chehab dev_err(&dev->udev->dev, 970*ce8591ffSMauro Carvalho Chehab "%s: i2c_add_adapter failed! retval [%d]\n", 9710c0d06caSMauro Carvalho Chehab __func__, retval); 9720c0d06caSMauro Carvalho Chehab return retval; 9730c0d06caSMauro Carvalho Chehab } 9740c0d06caSMauro Carvalho Chehab 975aab3125cSMauro Carvalho Chehab dev->i2c_client[bus] = em28xx_client_template; 976aab3125cSMauro Carvalho Chehab dev->i2c_client[bus].adapter = &dev->i2c_adap[bus]; 9770c0d06caSMauro Carvalho Chehab 978aab3125cSMauro Carvalho Chehab /* Up to now, all eeproms are at bus 0 */ 979aab3125cSMauro Carvalho Chehab if (!bus) { 980aab3125cSMauro Carvalho Chehab retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len); 9810c0d06caSMauro Carvalho Chehab if ((retval < 0) && (retval != -ENODEV)) { 982*ce8591ffSMauro Carvalho Chehab dev_err(&dev->udev->dev, 983*ce8591ffSMauro Carvalho Chehab "%s: em28xx_i2_eeprom failed! retval [%d]\n", 9840c0d06caSMauro Carvalho Chehab __func__, retval); 9850c0d06caSMauro Carvalho Chehab 9860c0d06caSMauro Carvalho Chehab return retval; 9870c0d06caSMauro Carvalho Chehab } 988aab3125cSMauro Carvalho Chehab } 9890c0d06caSMauro Carvalho Chehab 9900c0d06caSMauro Carvalho Chehab if (i2c_scan) 991aab3125cSMauro Carvalho Chehab em28xx_do_i2c_scan(dev, bus); 9920c0d06caSMauro Carvalho Chehab 9930c0d06caSMauro Carvalho Chehab return 0; 9940c0d06caSMauro Carvalho Chehab } 9950c0d06caSMauro Carvalho Chehab 9960c0d06caSMauro Carvalho Chehab /* 9970c0d06caSMauro Carvalho Chehab * em28xx_i2c_unregister() 9980c0d06caSMauro Carvalho Chehab * unregister i2c_bus 9990c0d06caSMauro Carvalho Chehab */ 1000aab3125cSMauro Carvalho Chehab int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus) 10010c0d06caSMauro Carvalho Chehab { 1002aab3125cSMauro Carvalho Chehab if (bus >= NUM_I2C_BUSES) 1003aab3125cSMauro Carvalho Chehab return -ENODEV; 1004aab3125cSMauro Carvalho Chehab 1005aab3125cSMauro Carvalho Chehab i2c_del_adapter(&dev->i2c_adap[bus]); 10060c0d06caSMauro Carvalho Chehab return 0; 10070c0d06caSMauro Carvalho Chehab } 1008