Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc5d0f8a authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Mauro Carvalho Chehab
Browse files

[media] V4L2: em28xx: register a V4L2 clock source



Camera sensors usually require a master clock for data sampling. This patch
registers such a clock source for em28xx cameras. This fixes the currently
broken em28xx ov2640 camera support and can also be used by other camera
sensors.

Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 774cc4c2
Loading
Loading
Loading
Loading
+31 −10
Original line number Original line Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/i2c.h>
#include <media/soc_camera.h>
#include <media/soc_camera.h>
#include <media/mt9v011.h>
#include <media/mt9v011.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-common.h>


#include "em28xx.h"
#include "em28xx.h"
@@ -325,13 +326,24 @@ int em28xx_detect_sensor(struct em28xx *dev)


int em28xx_init_camera(struct em28xx *dev)
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];
	int ret = 0;

	v4l2_clk_name_i2c(clk_name, sizeof(clk_name),
			  i2c_adapter_id(adap), client->addr);
	dev->clk = v4l2_clk_register_fixed(clk_name, "mclk", -EINVAL);
	if (IS_ERR(dev->clk))
		return PTR_ERR(dev->clk);

	switch (dev->em28xx_sensor) {
	switch (dev->em28xx_sensor) {
	case EM28XX_MT9V011:
	case EM28XX_MT9V011:
	{
	{
		struct mt9v011_platform_data pdata;
		struct mt9v011_platform_data pdata;
		struct i2c_board_info mt9v011_info = {
		struct i2c_board_info mt9v011_info = {
			.type = "mt9v011",
			.type = "mt9v011",
			.addr = dev->i2c_client[dev->def_i2c_bus].addr,
			.addr = client->addr,
			.platform_data = &pdata,
			.platform_data = &pdata,
		};
		};


@@ -352,10 +364,11 @@ int em28xx_init_camera(struct em28xx *dev)
		dev->sensor_xtal = 4300000;
		dev->sensor_xtal = 4300000;
		pdata.xtal = dev->sensor_xtal;
		pdata.xtal = dev->sensor_xtal;
		if (NULL ==
		if (NULL ==
		    v4l2_i2c_new_subdev_board(&dev->v4l2_dev,
		    v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap,
					      &dev->i2c_adap[dev->def_i2c_bus],
					      &mt9v011_info, NULL)) {
					      &mt9v011_info, NULL))
			ret = -ENODEV;
			return -ENODEV;
			break;
		}
		/* probably means GRGB 16 bit bayer */
		/* probably means GRGB 16 bit bayer */
		dev->vinmode = 0x0d;
		dev->vinmode = 0x0d;
		dev->vinctl = 0x00;
		dev->vinctl = 0x00;
@@ -391,7 +404,7 @@ int em28xx_init_camera(struct em28xx *dev)
		struct i2c_board_info ov2640_info = {
		struct i2c_board_info ov2640_info = {
			.type = "ov2640",
			.type = "ov2640",
			.flags = I2C_CLIENT_SCCB,
			.flags = I2C_CLIENT_SCCB,
			.addr = dev->i2c_client[dev->def_i2c_bus].addr,
			.addr = client->addr,
			.platform_data = &camlink,
			.platform_data = &camlink,
		};
		};
		struct v4l2_mbus_framefmt fmt;
		struct v4l2_mbus_framefmt fmt;
@@ -408,9 +421,12 @@ int em28xx_init_camera(struct em28xx *dev)
		dev->sensor_yres = 480;
		dev->sensor_yres = 480;


		subdev =
		subdev =
		     v4l2_i2c_new_subdev_board(&dev->v4l2_dev,
		     v4l2_i2c_new_subdev_board(&dev->v4l2_dev, adap,
					       &dev->i2c_adap[dev->def_i2c_bus],
					       &ov2640_info, NULL);
					       &ov2640_info, NULL);
		if (NULL == subdev) {
			ret = -ENODEV;
			break;
		}


		fmt.code = V4L2_MBUS_FMT_YUYV8_2X8;
		fmt.code = V4L2_MBUS_FMT_YUYV8_2X8;
		fmt.width = 640;
		fmt.width = 640;
@@ -427,8 +443,13 @@ int em28xx_init_camera(struct em28xx *dev)
	}
	}
	case EM28XX_NOSENSOR:
	case EM28XX_NOSENSOR:
	default:
	default:
		return -EINVAL;
		ret = -EINVAL;
	}
	}


	return 0;
	if (ret < 0) {
		v4l2_clk_unregister_fixed(dev->clk);
		dev->clk = NULL;
	}

	return ret;
}
}
+3 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@
#include <media/tvaudio.h>
#include <media/tvaudio.h>
#include <media/i2c-addr.h>
#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/tveeprom.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>
#include <media/v4l2-common.h>


#include "em28xx.h"
#include "em28xx.h"
@@ -2857,6 +2858,8 @@ void em28xx_release_resources(struct em28xx *dev)
	if (dev->def_i2c_bus)
	if (dev->def_i2c_bus)
		em28xx_i2c_unregister(dev, 1);
		em28xx_i2c_unregister(dev, 1);
	em28xx_i2c_unregister(dev, 0);
	em28xx_i2c_unregister(dev, 0);
	if (dev->clk)
		v4l2_clk_unregister_fixed(dev->clk);


	v4l2_ctrl_handler_free(&dev->ctrl_handler);
	v4l2_ctrl_handler_free(&dev->ctrl_handler);


+1 −0
Original line number Original line Diff line number Diff line
@@ -492,6 +492,7 @@ struct em28xx {


	struct v4l2_device v4l2_dev;
	struct v4l2_device v4l2_dev;
	struct v4l2_ctrl_handler ctrl_handler;
	struct v4l2_ctrl_handler ctrl_handler;
	struct v4l2_clk *clk;
	struct em28xx_board board;
	struct em28xx_board board;


	/* Webcam specific fields */
	/* Webcam specific fields */