blob: 50b0791a68a5d45bfb4f1f195f6993e1d3503f69 [file] [log] [blame]
Mauro Carvalho Chehabf22e9e72018-03-03 10:43:14 -05001// SPDX-License-Identifier: GPL-2.0+
2//
3// em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
4//
5// Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
6// Markus Rechberger <mrechberger@gmail.com>
7// Mauro Carvalho Chehab <mchehab@infradead.org>
8// Sascha Sommer <saschasommer@freenet.de>
9// Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com>
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080020
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080021
Mauro Carvalho Chehab8314d402016-10-12 07:26:47 -030022#include "em28xx.h"
23
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080024#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -030028#include <linux/jiffies.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080029
Mauro Carvalho Chehab6c362c82007-10-29 23:36:12 -030030#include "tuner-xc2028.h"
Michael Krufky5e453dc2006-01-09 15:32:31 -020031#include <media/v4l2-common.h>
Mauro Carvalho Chehabd5e52652005-11-08 21:37:32 -080032#include <media/tuner.h>
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080033
34/* ----------------------------------------------------------- */
35
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030036static unsigned int i2c_scan;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080037module_param(i2c_scan, int, 0444);
38MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
39
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -030040static unsigned int i2c_debug;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080041module_param(i2c_debug, int, 0644);
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -030042MODULE_PARM_DESC(i2c_debug, "i2c debug message level (1: normal debug, 2: show I2C transfers)");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080043
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -020044#define dprintk(level, fmt, arg...) do { \
45 if (i2c_debug > level) \
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -020046 dev_printk(KERN_DEBUG, &dev->intf->dev, \
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -020047 "i2c: %s: " fmt, __func__, ## arg); \
48} while (0)
49
50
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -080051/*
Mauro Carvalho Chehabcf68c222018-03-01 12:54:06 -050052 * Time in msecs to wait for i2c xfers to finish.
53 * 35ms is the maximum time a SMBUS device could wait when
54 * clock stretching is used. As the transfer itself will take
55 * some time to happen, set it to 35 ms.
56 *
57 * Ok, I2C doesn't specify any limit. So, eventually, we may need
58 * to increase this timeout.
59 */
60#define EM28XX_I2C_XFER_TIMEOUT 35 /* ms */
61
62static int em28xx_i2c_timeout(struct em28xx *dev)
63{
64 int time = EM28XX_I2C_XFER_TIMEOUT;
65
66 switch (dev->i2c_speed & 0x03) {
67 case EM28XX_I2C_FREQ_25_KHZ:
68 time += 4; /* Assume 4 ms for transfers */
69 break;
70 case EM28XX_I2C_FREQ_100_KHZ:
71 case EM28XX_I2C_FREQ_400_KHZ:
72 time += 1; /* Assume 1 ms for transfers */
73 break;
74 default: /* EM28XX_I2C_FREQ_1_5_MHZ */
75 break;
76 }
77
78 return msecs_to_jiffies(time);
79}
80
81/*
Frank Schaeferf5ae3712013-01-03 14:27:02 -030082 * em2800_i2c_send_bytes()
83 * send up to 4 bytes to the em2800 i2c device
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -080084 */
Frank Schaeferf5ae3712013-01-03 14:27:02 -030085static int em2800_i2c_send_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -080086{
Mauro Carvalho Chehabcf68c222018-03-01 12:54:06 -050087 unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -080088 int ret;
Frank Schaefera6bad042012-12-16 14:23:27 -030089 u8 b2[6];
Frank Schaeferf5ae3712013-01-03 14:27:02 -030090
91 if (len < 1 || len > 4)
92 return -EOPNOTSUPP;
93
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -080094 BUG_ON(len < 1 || len > 4);
95 b2[5] = 0x80 + len - 1;
96 b2[4] = addr;
97 b2[3] = buf[0];
98 if (len > 1)
99 b2[2] = buf[1];
100 if (len > 2)
101 b2[1] = buf[2];
102 if (len > 3)
103 b2[0] = buf[3];
104
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300105 /* trigger write */
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800106 ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800107 if (ret != 2 + len) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200108 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200109 "failed to trigger write to i2c address 0x%x (error=%i)\n",
Frank Schaeferd230d5a2013-03-24 14:58:03 -0300110 addr, ret);
Frank Schaefer45f04e82013-01-03 14:27:05 -0300111 return (ret < 0) ? ret : -EIO;
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800112 }
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300113 /* wait for completion */
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300114 while (time_is_after_jiffies(timeout)) {
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800115 ret = dev->em28xx_read_reg(dev, 0x05);
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300116 if (ret == 0x80 + len - 1)
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800117 return len;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300118 if (ret == 0x94 + len - 1) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200119 dprintk(1, "R05 returned 0x%02x: I2C ACK error\n", ret);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300120 return -ENXIO;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300121 }
122 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200123 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200124 "failed to get i2c transfer status from bridge register (error=%i)\n",
Mauro Carvalho Chehab2a96f602016-10-12 07:32:23 -0300125 ret);
Frank Schaefer45f04e82013-01-03 14:27:05 -0300126 return ret;
127 }
Markus Rechbergere8e41da2006-02-07 06:49:11 -0200128 msleep(5);
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800129 }
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200130 dprintk(0, "write to i2c device at 0x%x timed out\n", addr);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300131 return -ETIMEDOUT;
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800132}
133
134/*
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800135 * em2800_i2c_recv_bytes()
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300136 * read up to 4 bytes from the em2800 i2c device
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800137 */
Frank Schaefera6bad042012-12-16 14:23:27 -0300138static int em2800_i2c_recv_bytes(struct em28xx *dev, u8 addr, u8 *buf, u16 len)
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800139{
Mauro Carvalho Chehabcf68c222018-03-01 12:54:06 -0500140 unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300141 u8 buf2[4];
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800142 int ret;
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300143 int i;
Frank Schaeferf5ae3712013-01-03 14:27:02 -0300144
145 if (len < 1 || len > 4)
146 return -EOPNOTSUPP;
147
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300148 /* trigger read */
149 buf2[1] = 0x84 + len - 1;
150 buf2[0] = addr;
151 ret = dev->em28xx_write_regs(dev, 0x04, buf2, 2);
152 if (ret != 2) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200153 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200154 "failed to trigger read from i2c address 0x%x (error=%i)\n",
155 addr, ret);
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300156 return (ret < 0) ? ret : -EIO;
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800157 }
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300158
159 /* wait for completion */
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300160 while (time_is_after_jiffies(timeout)) {
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300161 ret = dev->em28xx_read_reg(dev, 0x05);
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300162 if (ret == 0x84 + len - 1)
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300163 break;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300164 if (ret == 0x94 + len - 1) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200165 dprintk(1, "R05 returned 0x%02x: I2C ACK error\n",
166 ret);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300167 return -ENXIO;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300168 }
169 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200170 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200171 "failed to get i2c transfer status from bridge register (error=%i)\n",
172 ret);
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300173 return ret;
174 }
175 msleep(5);
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800176 }
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300177 if (ret != 0x84 + len - 1) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200178 dprintk(0, "read from i2c device at 0x%x timed out\n", addr);
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300179 }
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300180
181 /* get the received message */
182 ret = dev->em28xx_read_reg_req_len(dev, 0x00, 4-len, buf2, len);
183 if (ret != len) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200184 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200185 "reading from i2c device at 0x%x failed: couldn't get the received message from the bridge (error=%i)\n",
186 addr, ret);
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300187 return (ret < 0) ? ret : -EIO;
188 }
189 for (i = 0; i < len; i++)
190 buf[i] = buf2[len - 1 - i];
191
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800192 return ret;
193}
194
195/*
Frank Schaefer2fcc82d2013-01-03 14:27:03 -0300196 * em2800_i2c_check_for_device()
197 * check if there is an i2c device at the supplied address
198 */
199static int em2800_i2c_check_for_device(struct em28xx *dev, u8 addr)
200{
201 u8 buf;
202 int ret;
203
204 ret = em2800_i2c_recv_bytes(dev, addr, &buf, 1);
205 if (ret == 1)
206 return 0;
207 return (ret < 0) ? ret : -EIO;
208}
209
210/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800211 * em28xx_i2c_send_bytes()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800212 */
Frank Schaefera6bad042012-12-16 14:23:27 -0300213static int em28xx_i2c_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
214 u16 len, int stop)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800215{
Mauro Carvalho Chehabcf68c222018-03-01 12:54:06 -0500216 unsigned long timeout = jiffies + em28xx_i2c_timeout(dev);
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300217 int ret;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800218
Frank Schaeferf5ae3712013-01-03 14:27:02 -0300219 if (len < 1 || len > 64)
220 return -EOPNOTSUPP;
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300221 /*
222 * NOTE: limited by the USB ctrl message constraints
223 * Zero length reads always succeed, even if no device is connected
224 */
Frank Schaeferf5ae3712013-01-03 14:27:02 -0300225
Frank Schaefer45f04e82013-01-03 14:27:05 -0300226 /* Write to i2c device */
227 ret = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
228 if (ret != len) {
229 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200230 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200231 "writing to i2c device at 0x%x failed (error=%i)\n",
232 addr, ret);
Frank Schaefer45f04e82013-01-03 14:27:05 -0300233 return ret;
234 } else {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200235 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200236 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
237 len, addr, ret);
Frank Schaefer45f04e82013-01-03 14:27:05 -0300238 return -EIO;
239 }
240 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800241
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300242 /* wait for completion */
243 while (time_is_after_jiffies(timeout)) {
Mauro Carvalho Chehabbbc70e62011-07-09 19:36:11 -0300244 ret = dev->em28xx_read_reg(dev, 0x05);
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300245 if (ret == 0) /* success */
Frank Schaefer45f04e82013-01-03 14:27:05 -0300246 return len;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300247 if (ret == 0x10) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200248 dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
249 addr);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300250 return -ENXIO;
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300251 }
252 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200253 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200254 "failed to get i2c transfer status from bridge register (error=%i)\n",
255 ret);
Frank Schaefer45f04e82013-01-03 14:27:05 -0300256 return ret;
257 }
Mauro Carvalho Chehabbbc70e62011-07-09 19:36:11 -0300258 msleep(5);
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300259 /*
260 * NOTE: do we really have to wait for success ?
261 * Never seen anything else than 0x00 or 0x10
262 * (even with high payload) ...
263 */
Mauro Carvalho Chehabbbc70e62011-07-09 19:36:11 -0300264 }
Frank Schaefer123a17d2014-01-19 18:48:35 -0300265
266 if (ret == 0x02 || ret == 0x04) {
267 /* NOTE: these errors seem to be related to clock stretching */
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200268 dprintk(0,
269 "write to i2c device at 0x%x timed out (status=%i)\n",
270 addr, ret);
Frank Schaefer123a17d2014-01-19 18:48:35 -0300271 return -ETIMEDOUT;
272 }
273
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200274 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200275 "write to i2c device at 0x%x failed with unknown error (status=%i)\n",
276 addr, ret);
Frank Schaefer123a17d2014-01-19 18:48:35 -0300277 return -EIO;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800278}
279
280/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800281 * em28xx_i2c_recv_bytes()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800282 * read a byte from the i2c device
283 */
Frank Schaefera6bad042012-12-16 14:23:27 -0300284static int em28xx_i2c_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf, u16 len)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800285{
286 int ret;
Frank Schaeferf5ae3712013-01-03 14:27:02 -0300287
288 if (len < 1 || len > 64)
289 return -EOPNOTSUPP;
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300290 /*
291 * NOTE: limited by the USB ctrl message constraints
292 * Zero length reads always succeed, even if no device is connected
293 */
Frank Schaeferf5ae3712013-01-03 14:27:02 -0300294
Frank Schaefer45f04e82013-01-03 14:27:05 -0300295 /* Read data from i2c device */
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800296 ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
Frank Schaefer7f6301d2013-03-10 07:25:25 -0300297 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200298 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200299 "reading from i2c device at 0x%x failed (error=%i)\n",
300 addr, ret);
Frank Schaefer7f6301d2013-03-10 07:25:25 -0300301 return ret;
Frank Schaefer45f04e82013-01-03 14:27:05 -0300302 }
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300303 /*
304 * NOTE: some devices with two i2c busses have the bad habit to return 0
Frank Schaefer7f6301d2013-03-10 07:25:25 -0300305 * bytes if we are on bus B AND there was no write attempt to the
306 * specified slave address before AND no device is present at the
307 * requested slave address.
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300308 * Anyway, the next check will fail with -ENXIO in this case, so avoid
Frank Schaefer7f6301d2013-03-10 07:25:25 -0300309 * spamming the system log on device probing and do nothing here.
310 */
Frank Schaefer45f04e82013-01-03 14:27:05 -0300311
312 /* Check success of the i2c operation */
313 ret = dev->em28xx_read_reg(dev, 0x05);
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300314 if (ret == 0) /* success */
315 return len;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800316 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200317 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200318 "failed to get i2c transfer status from bridge register (error=%i)\n",
319 ret);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800320 return ret;
321 }
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300322 if (ret == 0x10) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200323 dprintk(1, "I2C ACK error on writing to addr 0x%02x\n",
324 addr);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300325 return -ENXIO;
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300326 }
Mauro Carvalho Chehab4b836262014-01-04 05:42:11 -0300327
Frank Schaefer123a17d2014-01-19 18:48:35 -0300328 if (ret == 0x02 || ret == 0x04) {
329 /* NOTE: these errors seem to be related to clock stretching */
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200330 dprintk(0,
331 "write to i2c device at 0x%x timed out (status=%i)\n",
332 addr, ret);
Frank Schaefer123a17d2014-01-19 18:48:35 -0300333 return -ETIMEDOUT;
334 }
335
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200336 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200337 "write to i2c device at 0x%x failed with unknown error (status=%i)\n",
338 addr, ret);
Frank Schaefer123a17d2014-01-19 18:48:35 -0300339 return -EIO;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800340}
341
342/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800343 * em28xx_i2c_check_for_device()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800344 * check if there is a i2c_device at the supplied address
345 */
Frank Schaefera6bad042012-12-16 14:23:27 -0300346static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800347{
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800348 int ret;
Frank Schaefer45f04e82013-01-03 14:27:05 -0300349 u8 buf;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800350
Frank Schaefer45f04e82013-01-03 14:27:05 -0300351 ret = em28xx_i2c_recv_bytes(dev, addr, &buf, 1);
352 if (ret == 1)
353 return 0;
354 return (ret < 0) ? ret : -EIO;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800355}
356
357/*
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300358 * em25xx_bus_B_send_bytes
359 * write bytes to the i2c device
360 */
361static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
362 u16 len)
363{
364 int ret;
365
366 if (len < 1 || len > 64)
367 return -EOPNOTSUPP;
368 /*
369 * NOTE: limited by the USB ctrl message constraints
370 * Zero length reads always succeed, even if no device is connected
371 */
372
373 /* Set register and write value */
374 ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len);
375 if (ret != len) {
376 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200377 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200378 "writing to i2c device at 0x%x failed (error=%i)\n",
379 addr, ret);
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300380 return ret;
381 } else {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200382 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200383 "%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
384 len, addr, ret);
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300385 return -EIO;
386 }
387 }
388 /* Check success */
389 ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
390 /*
391 * NOTE: the only error we've seen so far is
392 * 0x01 when the slave device is not present
393 */
394 if (!ret)
395 return len;
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300396 else if (ret > 0) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200397 dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300398 return -ENXIO;
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300399 }
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300400
401 return ret;
402 /*
403 * NOTE: With chip types (other chip IDs) which actually don't support
404 * this operation, it seems to succeed ALWAYS ! (even if there is no
405 * slave device or even no second i2c bus provided)
406 */
407}
408
409/*
410 * em25xx_bus_B_recv_bytes
411 * read bytes from the i2c device
412 */
413static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
414 u16 len)
415{
416 int ret;
417
418 if (len < 1 || len > 64)
419 return -EOPNOTSUPP;
420 /*
421 * NOTE: limited by the USB ctrl message constraints
422 * Zero length reads always succeed, even if no device is connected
423 */
424
425 /* Read value */
426 ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len);
427 if (ret < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200428 dev_warn(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200429 "reading from i2c device at 0x%x failed (error=%i)\n",
430 addr, ret);
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300431 return ret;
432 }
433 /*
434 * NOTE: some devices with two i2c busses have the bad habit to return 0
435 * bytes if we are on bus B AND there was no write attempt to the
436 * specified slave address before AND no device is present at the
437 * requested slave address.
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300438 * Anyway, the next check will fail with -ENXIO in this case, so avoid
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300439 * spamming the system log on device probing and do nothing here.
440 */
441
442 /* Check success */
443 ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
444 /*
445 * NOTE: the only error we've seen so far is
446 * 0x01 when the slave device is not present
447 */
448 if (!ret)
449 return len;
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300450 else if (ret > 0) {
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200451 dprintk(1, "Bus B R08 returned 0x%02x: I2C ACK error\n", ret);
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300452 return -ENXIO;
Mauro Carvalho Chehabd845fb32014-01-06 09:17:53 -0300453 }
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300454
455 return ret;
456 /*
457 * NOTE: With chip types (other chip IDs) which actually don't support
458 * this operation, it seems to succeed ALWAYS ! (even if there is no
459 * slave device or even no second i2c bus provided)
460 */
461}
462
463/*
464 * em25xx_bus_B_check_for_device()
465 * check if there is a i2c device at the supplied address
466 */
467static int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr)
468{
469 u8 buf;
470 int ret;
471
472 ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1);
473 if (ret < 0)
474 return ret;
475
476 return 0;
477 /*
478 * NOTE: With chips which do not support this operation,
479 * it seems to succeed ALWAYS ! (even if no device connected)
480 */
481}
482
483static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr)
484{
485 struct em28xx *dev = i2c_bus->dev;
486 int rc = -EOPNOTSUPP;
487
488 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
489 rc = em28xx_i2c_check_for_device(dev, addr);
490 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
491 rc = em2800_i2c_check_for_device(dev, addr);
492 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
493 rc = em25xx_bus_B_check_for_device(dev, addr);
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300494 return rc;
495}
496
497static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
498 struct i2c_msg msg)
499{
500 struct em28xx *dev = i2c_bus->dev;
501 u16 addr = msg.addr << 1;
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300502 int rc = -EOPNOTSUPP;
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300503
504 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
505 rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
506 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
507 rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
508 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
509 rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len);
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300510 return rc;
511}
512
513static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus,
514 struct i2c_msg msg, int stop)
515{
516 struct em28xx *dev = i2c_bus->dev;
517 u16 addr = msg.addr << 1;
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300518 int rc = -EOPNOTSUPP;
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300519
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300520 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
521 rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop);
522 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
523 rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len);
524 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
525 rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len);
526 return rc;
527}
528
529/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800530 * em28xx_i2c_xfer()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800531 * the main i2c transfer function
532 */
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800533static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800534 struct i2c_msg msgs[], int num)
535{
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300536 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
537 struct em28xx *dev = i2c_bus->dev;
538 unsigned bus = i2c_bus->bus;
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300539 int addr, rc, i;
Mauro Carvalho Chehab3190fbe2013-03-21 06:03:27 -0300540 u8 reg;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800541
Shuah Khancc5c5d22014-07-11 18:25:55 -0300542 /* prevent i2c xfer attempts after device is disconnected
543 some fe's try to do i2c writes/reads from their release
544 interfaces when called in disconnect path */
545 if (dev->disconnected)
546 return -ENODEV;
547
Dan Carpentere44c1532016-05-09 05:22:55 -0300548 if (!rt_mutex_trylock(&dev->i2c_bus_lock))
549 return -EAGAIN;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300550
551 /* Switch I2C bus if needed */
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300552 if (bus != dev->cur_i2c_bus &&
553 i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) {
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300554 if (bus == 1)
Mauro Carvalho Chehab3190fbe2013-03-21 06:03:27 -0300555 reg = EM2874_I2C_SECONDARY_BUS_SELECT;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300556 else
Mauro Carvalho Chehab3190fbe2013-03-21 06:03:27 -0300557 reg = 0;
558 em28xx_write_reg_bits(dev, EM28XX_R06_I2C_CLK, reg,
559 EM2874_I2C_SECONDARY_BUS_SELECT);
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300560 dev->cur_i2c_bus = bus;
561 }
562
563 if (num <= 0) {
564 rt_mutex_unlock(&dev->i2c_bus_lock);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800565 return 0;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300566 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800567 for (i = 0; i < num; i++) {
568 addr = msgs[i].addr << 1;
Mauro Carvalho Chehabe63b0092014-01-04 05:42:11 -0300569 if (!msgs[i].len) {
570 /*
571 * no len: check only for device presence
572 * This code is only called during device probe.
573 */
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300574 rc = i2c_check_for_device(i2c_bus, addr);
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200575
576 if (rc == -ENXIO)
577 rc = -ENODEV;
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800578 } else if (msgs[i].flags & I2C_M_RD) {
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800579 /* read bytes */
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300580 rc = i2c_recv_bytes(i2c_bus, msgs[i]);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800581 } else {
582 /* write bytes */
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300583 rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800584 }
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200585
586 if (rc < 0)
587 goto error;
588
589 dprintk(2, "%s %s addr=%02x len=%d: %*ph\n",
590 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
591 i == num - 1 ? "stop" : "nonstop",
592 addr, msgs[i].len,
593 msgs[i].len, msgs[i].buf);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800594 }
595
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300596 rt_mutex_unlock(&dev->i2c_bus_lock);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800597 return num;
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200598
599error:
600 dprintk(2, "%s %s addr=%02x len=%d: %sERROR: %i\n",
601 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
602 i == num - 1 ? "stop" : "nonstop",
603 addr, msgs[i].len,
604 (rc == -ENODEV) ? "no device " : "",
605 rc);
606
607 rt_mutex_unlock(&dev->i2c_bus_lock);
608 return rc;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800609}
610
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300611/*
612 * based on linux/sunrpc/svcauth.h and linux/hash.h
Mauro Carvalho Chehab03910cc2007-11-03 21:20:59 -0300613 * The original hash function returns a different value, if arch is x86_64
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300614 * or i386.
Mauro Carvalho Chehab03910cc2007-11-03 21:20:59 -0300615 */
616static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits)
617{
618 unsigned long hash = 0;
619 unsigned long l = 0;
620 int len = 0;
621 unsigned char c;
Mauro Carvalho Chehabfdf1bc92014-11-28 08:34:15 -0300622
Mauro Carvalho Chehab03910cc2007-11-03 21:20:59 -0300623 do {
624 if (len == length) {
625 c = (char)len;
626 len = -1;
627 } else
628 c = *buf++;
629 l = (l << 8) | c;
630 len++;
631 if ((len & (32 / 8 - 1)) == 0)
632 hash = ((hash^l) * 0x9e370001UL);
633 } while (len);
634
635 return (hash >> (32 - bits)) & 0xffffffffUL;
636}
637
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300638/*
639 * Helper function to read data blocks from i2c clients with 8 or 16 bit
640 * address width, 8 bit register width and auto incrementation been activated
641 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300642static int em28xx_i2c_read_block(struct em28xx *dev, unsigned bus, u16 addr,
643 bool addr_w16, u16 len, u8 *data)
Frank Schaeferd832c5b2013-03-03 15:37:41 -0300644{
645 int remain = len, rsize, rsize_max, ret;
646 u8 buf[2];
647
648 /* Sanity check */
649 if (addr + remain > (addr_w16 * 0xff00 + 0xff + 1))
650 return -EINVAL;
651 /* Select address */
652 buf[0] = addr >> 8;
653 buf[1] = addr & 0xff;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300654 ret = i2c_master_send(&dev->i2c_client[bus], buf + !addr_w16, 1 + addr_w16);
Frank Schaeferd832c5b2013-03-03 15:37:41 -0300655 if (ret < 0)
656 return ret;
657 /* Read data */
658 if (dev->board.is_em2800)
659 rsize_max = 4;
660 else
661 rsize_max = 64;
662 while (remain > 0) {
663 if (remain > rsize_max)
664 rsize = rsize_max;
665 else
666 rsize = remain;
667
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300668 ret = i2c_master_recv(&dev->i2c_client[bus], data, rsize);
Frank Schaeferd832c5b2013-03-03 15:37:41 -0300669 if (ret < 0)
670 return ret;
671
672 remain -= rsize;
673 data += rsize;
674 }
675
676 return len;
677}
678
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300679static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned bus,
680 u8 **eedata, u16 *eedata_len)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800681{
Frank Schaefer510e8842013-03-03 15:37:43 -0300682 const u16 len = 256;
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300683 /*
684 * FIXME common length/size for bytes to read, to display, hash
Frank Schaefer510e8842013-03-03 15:37:43 -0300685 * calculation and returned device dataset. Simplifies the code a lot,
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300686 * but we might have to deal with multiple sizes in the future !
687 */
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300688 int err;
Frank Schaefer510e8842013-03-03 15:37:43 -0300689 struct em28xx_eeprom *dev_config;
690 u8 buf, *data;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800691
Frank Schaefera2179682013-03-03 15:37:42 -0300692 *eedata = NULL;
Frank Schaefer510e8842013-03-03 15:37:43 -0300693 *eedata_len = 0;
Frank Schaefera2179682013-03-03 15:37:42 -0300694
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300695 /* EEPROM is always on i2c bus 0 on all known devices. */
696
697 dev->i2c_client[bus].addr = 0xa0 >> 1;
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800698
699 /* Check if board has eeprom */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300700 err = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300701 if (err < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200702 dev_info(&dev->intf->dev, "board has no eeprom\n");
Mauro Carvalho Chehabc41109f2008-11-15 23:44:14 -0300703 return -ENODEV;
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300704 }
Mauro Carvalho Chehab596d92d2005-11-08 21:37:24 -0800705
Frank Schaefera2179682013-03-03 15:37:42 -0300706 data = kzalloc(len, GFP_KERNEL);
707 if (data == NULL)
708 return -ENOMEM;
709
Frank Schaeferd832c5b2013-03-03 15:37:41 -0300710 /* Read EEPROM content */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300711 err = em28xx_i2c_read_block(dev, bus, 0x0000,
712 dev->eeprom_addrwidth_16bit,
Frank Schaefera2179682013-03-03 15:37:42 -0300713 len, data);
Frank Schaeferd832c5b2013-03-03 15:37:41 -0300714 if (err != len) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200715 dev_err(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200716 "failed to read eeprom (err=%d)\n", err);
Frank Schaefer510e8842013-03-03 15:37:43 -0300717 goto error;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800718 }
Frank Schaefer90271962013-01-03 14:27:06 -0300719
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300720 if (i2c_debug) {
721 /* Display eeprom content */
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200722 print_hex_dump(KERN_DEBUG, "em28xx eeprom ", DUMP_PREFIX_OFFSET,
Mauro Carvalho Chehab50f0a9d2013-12-28 08:23:30 -0300723 16, 1, data, len, true);
724
725 if (dev->eeprom_addrwidth_16bit)
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200726 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200727 "eeprom %06x: ... (skipped)\n", 256);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800728 }
729
Frank Schaefer87b52432013-03-03 15:37:40 -0300730 if (dev->eeprom_addrwidth_16bit &&
Frank Schaefera2179682013-03-03 15:37:42 -0300731 data[0] == 0x26 && data[3] == 0x00) {
Frank Schaefer87b52432013-03-03 15:37:40 -0300732 /* new eeprom format; size 4-64kb */
Frank Schaefer510e8842013-03-03 15:37:43 -0300733 u16 mc_start;
734 u16 hwconf_offset;
735
Frank Schaefera2179682013-03-03 15:37:42 -0300736 dev->hash = em28xx_hash_mem(data, len, 32);
Frank Schaefer510e8842013-03-03 15:37:43 -0300737 mc_start = (data[1] << 8) + 4; /* usually 0x0004 */
738
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200739 dev_info(&dev->intf->dev,
Antonio Cardace290ef7d2018-02-09 09:13:26 -0500740 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
741 data, dev->hash);
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200742 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200743 "EEPROM info:\n");
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200744 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200745 "\tmicrocode start address = 0x%04x, boot configuration = 0x%02x\n",
746 mc_start, data[2]);
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300747 /*
748 * boot configuration (address 0x0002):
Frank Schaefer87b52432013-03-03 15:37:40 -0300749 * [0] microcode download speed: 1 = 400 kHz; 0 = 100 kHz
750 * [1] always selects 12 kb RAM
751 * [2] USB device speed: 1 = force Full Speed; 0 = auto detect
752 * [4] 1 = force fast mode and no suspend for device testing
753 * [5:7] USB PHY tuning registers; determined by device
754 * characterization
755 */
756
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300757 /*
758 * Read hardware config dataset offset from address
759 * (microcode start + 46)
760 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300761 err = em28xx_i2c_read_block(dev, bus, mc_start + 46, 1, 2,
762 data);
Frank Schaefer510e8842013-03-03 15:37:43 -0300763 if (err != 2) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200764 dev_err(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200765 "failed to read hardware configuration data from eeprom (err=%d)\n",
766 err);
Frank Schaefer510e8842013-03-03 15:37:43 -0300767 goto error;
768 }
Frank Schaefer87b52432013-03-03 15:37:40 -0300769
Frank Schaefer510e8842013-03-03 15:37:43 -0300770 /* Calculate hardware config dataset start address */
771 hwconf_offset = mc_start + data[0] + (data[1] << 8);
772
773 /* Read hardware config dataset */
Frank Schaeferfa74aca2013-03-24 17:09:59 -0300774 /*
775 * NOTE: the microcode copy can be multiple pages long, but
Frank Schaefer510e8842013-03-03 15:37:43 -0300776 * we assume the hardware config dataset is the same as in
777 * the old eeprom and not longer than 256 bytes.
778 * tveeprom is currently also limited to 256 bytes.
779 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300780 err = em28xx_i2c_read_block(dev, bus, hwconf_offset, 1, len,
781 data);
Frank Schaefer510e8842013-03-03 15:37:43 -0300782 if (err != len) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200783 dev_err(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200784 "failed to read hardware configuration data from eeprom (err=%d)\n",
785 err);
Frank Schaefer510e8842013-03-03 15:37:43 -0300786 goto error;
787 }
788
789 /* Verify hardware config dataset */
790 /* NOTE: not all devices provide this type of dataset */
791 if (data[0] != 0x1a || data[1] != 0xeb ||
792 data[2] != 0x67 || data[3] != 0x95) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200793 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200794 "\tno hardware configuration dataset found in eeprom\n");
Frank Schaefer510e8842013-03-03 15:37:43 -0300795 kfree(data);
796 return 0;
797 }
798
799 /* TODO: decrypt eeprom data for camera bridges (em25xx, em276x+) */
800
801 } else if (!dev->eeprom_addrwidth_16bit &&
802 data[0] == 0x1a && data[1] == 0xeb &&
803 data[2] == 0x67 && data[3] == 0x95) {
804 dev->hash = em28xx_hash_mem(data, len, 32);
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200805 dev_info(&dev->intf->dev,
Antonio Cardace290ef7d2018-02-09 09:13:26 -0500806 "EEPROM ID = %4ph, EEPROM hash = 0x%08lx\n",
807 data, dev->hash);
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200808 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200809 "EEPROM info:\n");
Frank Schaefer510e8842013-03-03 15:37:43 -0300810 } else {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200811 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200812 "unknown eeprom format or eeprom corrupted !\n");
Frank Schaefer510e8842013-03-03 15:37:43 -0300813 err = -ENODEV;
814 goto error;
Frank Schaeferf55eacb2013-03-03 15:37:37 -0300815 }
816
Frank Schaefera2179682013-03-03 15:37:42 -0300817 *eedata = data;
Frank Schaefer510e8842013-03-03 15:37:43 -0300818 *eedata_len = len;
Alban Browaeys32bf7c62013-07-16 18:57:53 -0300819 dev_config = (void *)*eedata;
Frank Schaefera2179682013-03-03 15:37:42 -0300820
Frank Schaefer510e8842013-03-03 15:37:43 -0300821 switch (le16_to_cpu(dev_config->chip_conf) >> 4 & 0x3) {
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800822 case 0:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200823 dev_info(&dev->intf->dev, "\tNo audio on board.\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800824 break;
825 case 1:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200826 dev_info(&dev->intf->dev, "\tAC97 audio (5 sample rates)\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800827 break;
828 case 2:
Frank Schaefer687ff8b2013-12-22 11:17:46 -0300829 if (dev->chip_id < CHIP_ID_EM2860)
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200830 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200831 "\tI2S audio, sample rate=32k\n");
Frank Schaefer687ff8b2013-12-22 11:17:46 -0300832 else
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200833 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200834 "\tI2S audio, 3 sample rates\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800835 break;
836 case 3:
Frank Schaefer687ff8b2013-12-22 11:17:46 -0300837 if (dev->chip_id < CHIP_ID_EM2860)
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200838 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200839 "\tI2S audio, 3 sample rates\n");
Frank Schaefer687ff8b2013-12-22 11:17:46 -0300840 else
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200841 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200842 "\tI2S audio, 5 sample rates\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800843 break;
844 }
845
Frank Schaefer510e8842013-03-03 15:37:43 -0300846 if (le16_to_cpu(dev_config->chip_conf) & 1 << 3)
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200847 dev_info(&dev->intf->dev, "\tUSB Remote wakeup capable\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800848
Frank Schaefer510e8842013-03-03 15:37:43 -0300849 if (le16_to_cpu(dev_config->chip_conf) & 1 << 2)
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200850 dev_info(&dev->intf->dev, "\tUSB Self power capable\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800851
Frank Schaefer510e8842013-03-03 15:37:43 -0300852 switch (le16_to_cpu(dev_config->chip_conf) & 0x3) {
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800853 case 0:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200854 dev_info(&dev->intf->dev, "\t500mA max power\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800855 break;
856 case 1:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200857 dev_info(&dev->intf->dev, "\t400mA max power\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800858 break;
859 case 2:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200860 dev_info(&dev->intf->dev, "\t300mA max power\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800861 break;
862 case 3:
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200863 dev_info(&dev->intf->dev, "\t200mA max power\n");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800864 break;
865 }
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200866 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200867 "\tTable at offset 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
868 dev_config->string_idx_table,
869 le16_to_cpu(dev_config->string1),
870 le16_to_cpu(dev_config->string2),
871 le16_to_cpu(dev_config->string3));
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800872
873 return 0;
Frank Schaefer510e8842013-03-03 15:37:43 -0300874
875error:
876 kfree(data);
877 return err;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800878}
879
880/* ----------------------------------------------------------- */
881
882/*
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800883 * functionality()
884 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300885static u32 functionality(struct i2c_adapter *i2c_adap)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800886{
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300887 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300888
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300889 if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) ||
890 (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) {
891 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
892 } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) {
893 return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) &
894 ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
895 }
896
897 WARN(1, "Unknown i2c bus algorithm.\n");
898 return 0;
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800899}
900
Julia Lawall78f2c502016-08-29 10:12:01 -0300901static const struct i2c_algorithm em28xx_algo = {
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800902 .master_xfer = em28xx_i2c_xfer,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800903 .functionality = functionality,
904};
905
Bhumika Goyal68438682017-08-19 06:34:15 -0400906static const struct i2c_adapter em28xx_adap_template = {
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800907 .owner = THIS_MODULE,
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800908 .name = "em28xx",
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800909 .algo = &em28xx_algo,
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800910};
911
Bhumika Goyal2b832472017-08-28 03:21:35 -0400912static const struct i2c_client em28xx_client_template = {
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800913 .name = "em28xx internal",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800914};
915
916/* ----------------------------------------------------------- */
917
918/*
919 * i2c_devs
920 * incomplete list of known devices
921 */
922static char *i2c_devs[128] = {
Wilson Michaels9aa785b2014-11-11 19:43:51 -0300923 [0x1c >> 1] = "lgdt330x",
Frank Schaefer0b3966e2013-01-13 10:15:08 -0300924 [0x3e >> 1] = "remote IR sensor",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800925 [0x4a >> 1] = "saa7113h",
Martin Blumenstingl729841e2012-06-12 18:19:27 -0300926 [0x52 >> 1] = "drxk",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800927 [0x60 >> 1] = "remote IR sensor",
Markus Rechbergerda45a2a2005-11-08 21:37:31 -0800928 [0x8e >> 1] = "remote IR sensor",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800929 [0x86 >> 1] = "tda9887",
930 [0x80 >> 1] = "msp34xx",
931 [0x88 >> 1] = "msp34xx",
932 [0xa0 >> 1] = "eeprom",
Vitaly Wool2bd1d9eb2009-03-04 08:27:52 -0300933 [0xb0 >> 1] = "tda9874",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800934 [0xb8 >> 1] = "tvp5150a",
Mauro Carvalho Chehab791a08f2009-07-03 15:36:18 -0300935 [0xba >> 1] = "webcam sensor or tvp5150a",
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800936 [0xc0 >> 1] = "tuner (analog)",
937 [0xc2 >> 1] = "tuner (analog)",
938 [0xc4 >> 1] = "tuner (analog)",
939 [0xc6 >> 1] = "tuner (analog)",
940};
941
942/*
943 * do_i2c_scan()
944 * check i2c address range for devices
945 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300946void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800947{
Sascha Sommerfad7b952007-11-04 08:06:48 -0300948 u8 i2c_devicelist[128];
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800949 unsigned char buf;
950 int i, rc;
951
Sascha Sommerfad7b952007-11-04 08:06:48 -0300952 memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist));
953
Mauro Carvalho Chehab53c4e952007-03-29 08:42:30 -0300954 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300955 dev->i2c_client[bus].addr = i;
956 rc = i2c_master_recv(&dev->i2c_client[bus], &buf, 0);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800957 if (rc < 0)
958 continue;
Sascha Sommerfad7b952007-11-04 08:06:48 -0300959 i2c_devicelist[i] = i;
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200960 dev_info(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200961 "found i2c device @ 0x%x on bus %d [%s]\n",
962 i << 1, bus, i2c_devs[i] ? i2c_devs[i] : "???");
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800963 }
Sascha Sommerfad7b952007-11-04 08:06:48 -0300964
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300965 if (bus == dev->def_i2c_bus)
966 dev->i2c_hash = em28xx_hash_mem(i2c_devicelist,
967 ARRAY_SIZE(i2c_devicelist), 32);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800968}
969
970/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800971 * em28xx_i2c_register()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800972 * register i2c bus
973 */
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300974int em28xx_i2c_register(struct em28xx *dev, unsigned bus,
975 enum em28xx_i2c_algo_type algo_type)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -0800976{
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300977 int retval;
978
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -0800979 BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
980 BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300981
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300982 if (bus >= NUM_I2C_BUSES)
983 return -ENODEV;
984
985 dev->i2c_adap[bus] = em28xx_adap_template;
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200986 dev->i2c_adap[bus].dev.parent = &dev->intf->dev;
987 strcpy(dev->i2c_adap[bus].name, dev_name(&dev->intf->dev));
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300988
989 dev->i2c_bus[bus].bus = bus;
Frank Schaefera3ea4bf2013-03-26 13:38:36 -0300990 dev->i2c_bus[bus].algo_type = algo_type;
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300991 dev->i2c_bus[bus].dev = dev;
992 dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus];
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -0300993
994 retval = i2c_add_adapter(&dev->i2c_adap[bus]);
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300995 if (retval < 0) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -0200996 dev_err(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -0200997 "%s: i2c_add_adapter failed! retval [%d]\n",
998 __func__, retval);
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -0300999 return retval;
1000 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001001
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001002 dev->i2c_client[bus] = em28xx_client_template;
1003 dev->i2c_client[bus].adapter = &dev->i2c_adap[bus];
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001004
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001005 /* Up to now, all eeproms are at bus 0 */
1006 if (!bus) {
1007 retval = em28xx_i2c_eeprom(dev, bus, &dev->eedata, &dev->eedata_len);
1008 if ((retval < 0) && (retval != -ENODEV)) {
Mauro Carvalho Chehab29b05e22016-12-07 13:48:10 -02001009 dev_err(&dev->intf->dev,
Mauro Carvalho Chehabce8591f2016-10-20 08:42:03 -02001010 "%s: em28xx_i2_eeprom failed! retval [%d]\n",
1011 __func__, retval);
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001012 }
Douglas Schilling Landgraff2a01a02008-09-08 03:27:20 -03001013 }
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001014
1015 if (i2c_scan)
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001016 em28xx_do_i2c_scan(dev, bus);
Mauro Carvalho Chehabc41109f2008-11-15 23:44:14 -03001017
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001018 return 0;
1019}
1020
1021/*
Mauro Carvalho Chehab3acf2802005-11-08 21:38:27 -08001022 * em28xx_i2c_unregister()
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001023 * unregister i2c_bus
1024 */
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001025int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus)
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001026{
Mauro Carvalho Chehabaab31252013-03-05 06:55:28 -03001027 if (bus >= NUM_I2C_BUSES)
1028 return -ENODEV;
1029
1030 i2c_del_adapter(&dev->i2c_adap[bus]);
akpm@osdl.orga6c2ba22005-11-08 21:37:07 -08001031 return 0;
1032}