0001
0002
0003
0004
0005
0006
0007
0008 #include "em28xx.h"
0009
0010 #include <linux/i2c.h>
0011 #include <linux/usb.h>
0012 #include <media/i2c/mt9v011.h>
0013 #include <media/v4l2-common.h>
0014
0015
0016 static unsigned short micron_sensor_addrs[] = {
0017 0xb8 >> 1,
0018 0xba >> 1,
0019 0x90 >> 1,
0020 I2C_CLIENT_END
0021 };
0022
0023
0024 static unsigned short omnivision_sensor_addrs[] = {
0025 0x42 >> 1,
0026 0x60 >> 1,
0027 I2C_CLIENT_END
0028 };
0029
0030
0031 static int em28xx_initialize_mt9m111(struct em28xx *dev)
0032 {
0033 int i;
0034 unsigned char regs[][3] = {
0035 { 0x0d, 0x00, 0x01, },
0036 { 0x0d, 0x00, 0x00, },
0037 { 0x0a, 0x00, 0x21, },
0038 { 0x21, 0x04, 0x00, },
0039 };
0040
0041 for (i = 0; i < ARRAY_SIZE(regs); i++)
0042 i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
0043 ®s[i][0], 3);
0044
0045
0046
0047 return 0;
0048 }
0049
0050
0051 static int em28xx_initialize_mt9m001(struct em28xx *dev)
0052 {
0053 int i;
0054 unsigned char regs[][3] = {
0055 { 0x0d, 0x00, 0x01, },
0056 { 0x0d, 0x00, 0x00, },
0057 { 0x04, 0x05, 0x00, },
0058 { 0x03, 0x04, 0x00, },
0059 { 0x20, 0x11, 0x00, },
0060 { 0x06, 0x00, 0x10, },
0061 { 0x2b, 0x00, 0x24, },
0062 { 0x2e, 0x00, 0x24, },
0063 { 0x35, 0x00, 0x24, },
0064 { 0x2d, 0x00, 0x20, },
0065 { 0x2c, 0x00, 0x20, },
0066 { 0x09, 0x0a, 0xd4, },
0067 { 0x35, 0x00, 0x57, },
0068 };
0069
0070 for (i = 0; i < ARRAY_SIZE(regs); i++)
0071 i2c_master_send(&dev->i2c_client[dev->def_i2c_bus],
0072 ®s[i][0], 3);
0073
0074
0075
0076 return 0;
0077 }
0078
0079
0080
0081
0082 static int em28xx_probe_sensor_micron(struct em28xx *dev)
0083 {
0084 int ret, i;
0085 char *name;
0086 u16 id;
0087
0088 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
0089
0090 dev->em28xx_sensor = EM28XX_NOSENSOR;
0091 for (i = 0; micron_sensor_addrs[i] != I2C_CLIENT_END; i++) {
0092 client->addr = micron_sensor_addrs[i];
0093
0094 ret = i2c_smbus_read_word_data(client, 0x00);
0095 if (ret < 0) {
0096 if (ret != -ENXIO)
0097 dev_err(&dev->intf->dev,
0098 "couldn't read from i2c device 0x%02x: error %i\n",
0099 client->addr << 1, ret);
0100 continue;
0101 }
0102 id = swab16(ret);
0103
0104 ret = i2c_smbus_read_word_data(client, 0xff);
0105 if (ret < 0) {
0106 dev_err(&dev->intf->dev,
0107 "couldn't read from i2c device 0x%02x: error %i\n",
0108 client->addr << 1, ret);
0109 continue;
0110 }
0111
0112 if (id != swab16(ret))
0113 continue;
0114
0115 switch (id) {
0116 case 0x1222:
0117 name = "MT9V012";
0118 break;
0119 case 0x1229:
0120 name = "MT9V112";
0121 break;
0122 case 0x1433:
0123 name = "MT9M011";
0124 break;
0125 case 0x143a:
0126 name = "MT9M111";
0127 dev->em28xx_sensor = EM28XX_MT9M111;
0128 break;
0129 case 0x148c:
0130 name = "MT9M112";
0131 break;
0132 case 0x1511:
0133 name = "MT9D011";
0134 break;
0135 case 0x8232:
0136 case 0x8243:
0137 name = "MT9V011";
0138 dev->em28xx_sensor = EM28XX_MT9V011;
0139 break;
0140 case 0x8431:
0141 name = "MT9M001";
0142 dev->em28xx_sensor = EM28XX_MT9M001;
0143 break;
0144 default:
0145 dev_info(&dev->intf->dev,
0146 "unknown Micron sensor detected: 0x%04x\n",
0147 id);
0148 return 0;
0149 }
0150
0151 if (dev->em28xx_sensor == EM28XX_NOSENSOR)
0152 dev_info(&dev->intf->dev,
0153 "unsupported sensor detected: %s\n", name);
0154 else
0155 dev_info(&dev->intf->dev,
0156 "sensor %s detected\n", name);
0157
0158 return 0;
0159 }
0160
0161 return -ENODEV;
0162 }
0163
0164
0165
0166
0167 static int em28xx_probe_sensor_omnivision(struct em28xx *dev)
0168 {
0169 int ret, i;
0170 char *name;
0171 u8 reg;
0172 u16 id;
0173 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
0174
0175 dev->em28xx_sensor = EM28XX_NOSENSOR;
0176
0177
0178
0179
0180 for (i = 0; omnivision_sensor_addrs[i] != I2C_CLIENT_END; i++) {
0181 client->addr = omnivision_sensor_addrs[i];
0182
0183 reg = 0x1c;
0184 ret = i2c_smbus_read_byte_data(client, reg);
0185 if (ret < 0) {
0186 if (ret != -ENXIO)
0187 dev_err(&dev->intf->dev,
0188 "couldn't read from i2c device 0x%02x: error %i\n",
0189 client->addr << 1, ret);
0190 continue;
0191 }
0192 id = ret << 8;
0193 reg = 0x1d;
0194 ret = i2c_smbus_read_byte_data(client, reg);
0195 if (ret < 0) {
0196 dev_err(&dev->intf->dev,
0197 "couldn't read from i2c device 0x%02x: error %i\n",
0198 client->addr << 1, ret);
0199 continue;
0200 }
0201 id += ret;
0202
0203 if (id != 0x7fa2)
0204 continue;
0205
0206 reg = 0x0a;
0207 ret = i2c_smbus_read_byte_data(client, reg);
0208 if (ret < 0) {
0209 dev_err(&dev->intf->dev,
0210 "couldn't read from i2c device 0x%02x: error %i\n",
0211 client->addr << 1, ret);
0212 continue;
0213 }
0214 id = ret << 8;
0215 reg = 0x0b;
0216 ret = i2c_smbus_read_byte_data(client, reg);
0217 if (ret < 0) {
0218 dev_err(&dev->intf->dev,
0219 "couldn't read from i2c device 0x%02x: error %i\n",
0220 client->addr << 1, ret);
0221 continue;
0222 }
0223 id += ret;
0224
0225 switch (id) {
0226 case 0x2642:
0227 name = "OV2640";
0228 dev->em28xx_sensor = EM28XX_OV2640;
0229 break;
0230 case 0x7648:
0231 name = "OV7648";
0232 break;
0233 case 0x7660:
0234 name = "OV7660";
0235 break;
0236 case 0x7673:
0237 name = "OV7670";
0238 break;
0239 case 0x7720:
0240 name = "OV7720";
0241 break;
0242 case 0x7721:
0243 name = "OV7725";
0244 break;
0245 case 0x9648:
0246 case 0x9649:
0247 name = "OV9640";
0248 break;
0249 case 0x9650:
0250 case 0x9652:
0251 name = "OV9650";
0252 break;
0253 case 0x9656:
0254 case 0x9657:
0255 name = "OV9655";
0256 break;
0257 default:
0258 dev_info(&dev->intf->dev,
0259 "unknown OmniVision sensor detected: 0x%04x\n",
0260 id);
0261 return 0;
0262 }
0263
0264 if (dev->em28xx_sensor == EM28XX_NOSENSOR)
0265 dev_info(&dev->intf->dev,
0266 "unsupported sensor detected: %s\n", name);
0267 else
0268 dev_info(&dev->intf->dev,
0269 "sensor %s detected\n", name);
0270
0271 return 0;
0272 }
0273
0274 return -ENODEV;
0275 }
0276
0277 int em28xx_detect_sensor(struct em28xx *dev)
0278 {
0279 int ret;
0280
0281 ret = em28xx_probe_sensor_micron(dev);
0282
0283 if (dev->em28xx_sensor == EM28XX_NOSENSOR && ret < 0)
0284 ret = em28xx_probe_sensor_omnivision(dev);
0285
0286
0287
0288
0289
0290
0291 if (dev->em28xx_sensor == EM28XX_NOSENSOR && ret < 0) {
0292 dev_info(&dev->intf->dev,
0293 "No sensor detected\n");
0294 return -ENODEV;
0295 }
0296
0297 return 0;
0298 }
0299
0300 int em28xx_init_camera(struct em28xx *dev)
0301 {
0302 struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus];
0303 struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus];
0304 struct em28xx_v4l2 *v4l2 = dev->v4l2;
0305
0306 switch (dev->em28xx_sensor) {
0307 case EM28XX_MT9V011:
0308 {
0309 struct mt9v011_platform_data pdata;
0310 struct i2c_board_info mt9v011_info = {
0311 .type = "mt9v011",
0312 .addr = client->addr,
0313 .platform_data = &pdata,
0314 };
0315
0316 v4l2->sensor_xres = 640;
0317 v4l2->sensor_yres = 480;
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
0329 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk);
0330 v4l2->sensor_xtal = 4300000;
0331 pdata.xtal = v4l2->sensor_xtal;
0332 if (NULL ==
0333 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
0334 &mt9v011_info, NULL))
0335 return -ENODEV;
0336 v4l2->vinmode = EM28XX_VINMODE_RGB8_GRBG;
0337 v4l2->vinctl = 0x00;
0338
0339 break;
0340 }
0341 case EM28XX_MT9M001:
0342 v4l2->sensor_xres = 1280;
0343 v4l2->sensor_yres = 1024;
0344
0345 em28xx_initialize_mt9m001(dev);
0346
0347 v4l2->vinmode = EM28XX_VINMODE_RGB8_BGGR;
0348 v4l2->vinctl = 0x00;
0349
0350 break;
0351 case EM28XX_MT9M111:
0352 v4l2->sensor_xres = 640;
0353 v4l2->sensor_yres = 512;
0354
0355 dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
0356 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk);
0357 em28xx_initialize_mt9m111(dev);
0358
0359 v4l2->vinmode = EM28XX_VINMODE_YUV422_UYVY;
0360 v4l2->vinctl = 0x00;
0361
0362 break;
0363 case EM28XX_OV2640:
0364 {
0365 struct v4l2_subdev *subdev;
0366 struct i2c_board_info ov2640_info = {
0367 .type = "ov2640",
0368 .flags = I2C_CLIENT_SCCB,
0369 .addr = client->addr,
0370 };
0371 struct v4l2_subdev_format format = {
0372 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
0373 };
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 v4l2->sensor_xres = 640;
0384 v4l2->sensor_yres = 480;
0385
0386 subdev =
0387 v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap,
0388 &ov2640_info, NULL);
0389 if (!subdev)
0390 return -ENODEV;
0391
0392 format.format.code = MEDIA_BUS_FMT_YUYV8_2X8;
0393 format.format.width = 640;
0394 format.format.height = 480;
0395 v4l2_subdev_call(subdev, pad, set_fmt, NULL, &format);
0396
0397
0398 dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ;
0399 em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk);
0400 v4l2->vinmode = EM28XX_VINMODE_YUV422_YUYV;
0401 v4l2->vinctl = 0x00;
0402
0403 break;
0404 }
0405 case EM28XX_NOSENSOR:
0406 default:
0407 return -EINVAL;
0408 }
0409
0410 return 0;
0411 }
0412 EXPORT_SYMBOL_GPL(em28xx_init_camera);