--- zzzz-none-000/linux-3.10.107/drivers/media/usb/em28xx/em28xx-camera.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/media/usb/em28xx/em28xx-camera.c 2021-02-04 17:41:59.000000000 +0000 @@ -22,11 +22,11 @@ #include #include #include +#include #include #include "em28xx.h" - /* Possible i2c addresses of Micron sensors */ static unsigned short micron_sensor_addrs[] = { 0xb8 >> 1, /* MT9V111, MT9V403 */ @@ -42,14 +42,13 @@ I2C_CLIENT_END }; - static struct soc_camera_link camlink = { .bus_id = 0, .flags = 0, .module_name = "em28xx", + .unbalanced_power = true, }; - /* FIXME: Should be replaced by a proper mt9m111 driver */ static int em28xx_initialize_mt9m111(struct em28xx *dev) { @@ -68,7 +67,6 @@ return 0; } - /* FIXME: Should be replaced by a proper mt9m001 driver */ static int em28xx_initialize_mt9m001(struct em28xx *dev) { @@ -96,7 +94,6 @@ return 0; } - /* * Probes Micron sensors with 8 bit address and 16 bit register width */ @@ -118,7 +115,7 @@ reg = 0x00; ret = i2c_master_send(&client, ®, 1); if (ret < 0) { - if (ret != -ENODEV) + if (ret != -ENXIO) em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -216,7 +213,7 @@ reg = 0x1c; ret = i2c_smbus_read_byte_data(&client, reg); if (ret < 0) { - if (ret != -ENODEV) + if (ret != -ENXIO) em28xx_errdev("couldn't read from i2c device 0x%02x: error %i\n", client.addr << 1, ret); continue; @@ -325,18 +322,30 @@ int em28xx_init_camera(struct em28xx *dev) { + char clk_name[V4L2_SUBDEV_NAME_SIZE]; + struct i2c_client *client = &dev->i2c_client[dev->def_i2c_bus]; + struct i2c_adapter *adap = &dev->i2c_adap[dev->def_i2c_bus]; + struct em28xx_v4l2 *v4l2 = dev->v4l2; + int ret = 0; + + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + i2c_adapter_id(adap), client->addr); + v4l2->clk = v4l2_clk_register_fixed(clk_name, -EINVAL); + if (IS_ERR(v4l2->clk)) + return PTR_ERR(v4l2->clk); + switch (dev->em28xx_sensor) { case EM28XX_MT9V011: { struct mt9v011_platform_data pdata; struct i2c_board_info mt9v011_info = { .type = "mt9v011", - .addr = dev->i2c_client[dev->def_i2c_bus].addr, + .addr = client->addr, .platform_data = &pdata, }; - dev->sensor_xres = 640; - dev->sensor_yres = 480; + v4l2->sensor_xres = 640; + v4l2->sensor_yres = 480; /* * FIXME: mt9v011 uses I2S speed as xtal clk - at least with @@ -349,40 +358,41 @@ */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); - dev->sensor_xtal = 4300000; - pdata.xtal = dev->sensor_xtal; + v4l2->sensor_xtal = 4300000; + pdata.xtal = v4l2->sensor_xtal; if (NULL == - v4l2_i2c_new_subdev_board(&dev->v4l2_dev, - &dev->i2c_adap[dev->def_i2c_bus], - &mt9v011_info, NULL)) - return -ENODEV; + v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, + &mt9v011_info, NULL)) { + ret = -ENODEV; + break; + } /* probably means GRGB 16 bit bayer */ - dev->vinmode = 0x0d; - dev->vinctl = 0x00; + v4l2->vinmode = 0x0d; + v4l2->vinctl = 0x00; break; } case EM28XX_MT9M001: - dev->sensor_xres = 1280; - dev->sensor_yres = 1024; + v4l2->sensor_xres = 1280; + v4l2->sensor_yres = 1024; em28xx_initialize_mt9m001(dev); /* probably means BGGR 16 bit bayer */ - dev->vinmode = 0x0c; - dev->vinctl = 0x00; + v4l2->vinmode = 0x0c; + v4l2->vinctl = 0x00; break; case EM28XX_MT9M111: - dev->sensor_xres = 640; - dev->sensor_yres = 512; + v4l2->sensor_xres = 640; + v4l2->sensor_yres = 512; dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); em28xx_initialize_mt9m111(dev); - dev->vinmode = 0x0a; - dev->vinctl = 0x00; + v4l2->vinmode = 0x0a; + v4l2->vinctl = 0x00; break; case EM28XX_OV2640: @@ -391,10 +401,12 @@ struct i2c_board_info ov2640_info = { .type = "ov2640", .flags = I2C_CLIENT_SCCB, - .addr = dev->i2c_client[dev->def_i2c_bus].addr, + .addr = client->addr, .platform_data = &camlink, }; - struct v4l2_mbus_framefmt fmt; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; /* * FIXME: sensor supports resolutions up to 1600x1200, but @@ -404,31 +416,40 @@ * - adjust bridge xclk * - disable 16 bit (12 bit) output formats on high resolutions */ - dev->sensor_xres = 640; - dev->sensor_yres = 480; + v4l2->sensor_xres = 640; + v4l2->sensor_yres = 480; subdev = - v4l2_i2c_new_subdev_board(&dev->v4l2_dev, - &dev->i2c_adap[dev->def_i2c_bus], + v4l2_i2c_new_subdev_board(&v4l2->v4l2_dev, adap, &ov2640_info, NULL); + if (NULL == subdev) { + ret = -ENODEV; + break; + } - fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; - fmt.width = 640; - fmt.height = 480; - v4l2_subdev_call(subdev, video, s_mbus_fmt, &fmt); + format.format.code = MEDIA_BUS_FMT_YUYV8_2X8; + format.format.width = 640; + format.format.height = 480; + v4l2_subdev_call(subdev, pad, set_fmt, NULL, &format); /* NOTE: for UXGA=1600x1200 switch to 12MHz */ dev->board.xclk = EM28XX_XCLK_FREQUENCY_24MHZ; em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); - dev->vinmode = 0x08; - dev->vinctl = 0x00; + v4l2->vinmode = 0x08; + v4l2->vinctl = 0x00; break; } case EM28XX_NOSENSOR: default: - return -EINVAL; + ret = -EINVAL; } - return 0; + if (ret < 0) { + v4l2_clk_unregister_fixed(v4l2->clk); + v4l2->clk = NULL; + } + + return ret; } +EXPORT_SYMBOL_GPL(em28xx_init_camera);