diff options
Diffstat (limited to 'drivers/media/i2c/soc_camera')
| -rw-r--r-- | drivers/media/i2c/soc_camera/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/imx074.c | 66 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9m001.c | 96 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9m111.c | 108 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9t031.c | 89 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9t112.c | 74 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9v022.c | 122 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov2640.c | 50 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov5642.c | 56 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov6650.c | 53 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov772x.c | 65 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov9640.c | 54 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov9640.h | 1 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/ov9740.c | 52 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/rj54n1cb0c.c | 81 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/tw9910.c | 64 |
16 files changed, 448 insertions, 585 deletions
diff --git a/drivers/media/i2c/soc_camera/Kconfig b/drivers/media/i2c/soc_camera/Kconfig index 6dff2b7ad52..23d352f0adf 100644 --- a/drivers/media/i2c/soc_camera/Kconfig +++ b/drivers/media/i2c/soc_camera/Kconfig @@ -9,7 +9,6 @@ config SOC_CAMERA_IMX074 config SOC_CAMERA_MT9M001 tristate "mt9m001 support" depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9M001_PCA9536_SWITCH help This driver supports MT9M001 cameras from Micron, monochrome and colour models. @@ -36,7 +35,6 @@ config SOC_CAMERA_MT9T112 config SOC_CAMERA_MT9V022 tristate "mt9v022 and mt9v024 support" depends on SOC_CAMERA && I2C - select GPIO_PCA953X if MT9V022_PCA9536_SWITCH help This driver supports MT9V022 cameras from Micron diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index f8534eec9de..5b915936c3f 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -18,8 +18,9 @@ #include <linux/module.h> #include <media/soc_camera.h> +#include <media/v4l2-async.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> -#include <media/v4l2-chip-ident.h> /* IMX074 registers */ @@ -77,6 +78,7 @@ struct imx074_datafmt { struct imx074 { struct v4l2_subdev subdev; const struct imx074_datafmt *fmt; + struct v4l2_clk *clk; }; static const struct imx074_datafmt imx074_colour_fmts[] = { @@ -251,29 +253,13 @@ static int imx074_s_stream(struct v4l2_subdev *sd, int enable) return reg_write(client, MODE_SELECT, !!enable); } -static int imx074_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = V4L2_IDENT_IMX074; - id->revision = 0; - - return 0; -} - static int imx074_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct imx074 *priv = to_imx074(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static int imx074_g_mbus_config(struct v4l2_subdev *sd, @@ -299,7 +285,6 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { }; static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { - .g_chip_ident = imx074_g_chip_ident, .s_power = imx074_s_power, }; @@ -430,10 +415,10 @@ static int imx074_probe(struct i2c_client *client, { struct imx074 *priv; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "IMX074: missing platform data!\n"); return -EINVAL; } @@ -444,7 +429,7 @@ static int imx074_probe(struct i2c_client *client, return -EIO; } - priv = kzalloc(sizeof(struct imx074), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(struct imx074), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -452,23 +437,40 @@ static int imx074_probe(struct i2c_client *client, priv->fmt = &imx074_colour_fmts[0]; - ret = imx074_video_probe(client); - if (ret < 0) { - kfree(priv); - return ret; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + dev_info(&client->dev, "Error %ld getting clock\n", PTR_ERR(priv->clk)); + return -EPROBE_DEFER; } + ret = soc_camera_power_init(&client->dev, ssdd); + if (ret < 0) + goto epwrinit; + + ret = imx074_video_probe(client); + if (ret < 0) + goto eprobe; + + ret = v4l2_async_register_subdev(&priv->subdev); + if (!ret) + return 0; + +epwrinit: +eprobe: + v4l2_clk_put(priv->clk); return ret; } static int imx074_remove(struct i2c_client *client) { + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct imx074 *priv = to_imx074(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); - if (icl->free_bus) - icl->free_bus(icl); - kfree(priv); + v4l2_async_unregister_subdev(&priv->subdev); + v4l2_clk_put(priv->clk); + + if (ssdd->free_bus) + ssdd->free_bus(ssdd); return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index 19f8a07764f..df97033fa6e 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -16,14 +16,14 @@ #include <media/soc_camera.h> #include <media/soc_mediabus.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> -#include <media/v4l2-chip-ident.h> #include <media/v4l2-ctrls.h> /* * mt9m001 i2c address 0x5d * The platform has to define struct i2c_board_info objects and link to them - * from struct soc_camera_link + * from struct soc_camera_host_desc */ /* mt9m001 selected register addresses */ @@ -94,10 +94,10 @@ struct mt9m001 { struct v4l2_ctrl *exposure; }; struct v4l2_rect rect; /* Sensor window */ + struct v4l2_clk *clk; const struct mt9m001_datafmt *fmt; const struct mt9m001_datafmt *fmts; int num_fmts; - int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ unsigned int total_h; unsigned short y_skip_top; /* Lines to skip at the top */ }; @@ -320,36 +320,15 @@ static int mt9m001_try_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9m001_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9m001 *mt9m001 = to_mt9m001(client); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = mt9m001->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m001_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - reg->size = 2; reg->val = reg_read(client, reg->reg); @@ -360,16 +339,13 @@ static int mt9m001_g_register(struct v4l2_subdev *sd, } static int mt9m001_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - if (reg_write(client, reg->reg, reg->val) < 0) return -EIO; @@ -380,9 +356,10 @@ static int mt9m001_s_register(struct v4l2_subdev *sd, static int mt9m001_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9m001 *mt9m001 = to_mt9m001(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, mt9m001->clk, on); } static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl) @@ -482,7 +459,7 @@ static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl) * Interface active, can use i2c. If it fails, it can indeed mean, that * this wasn't our capture interface, so, we wait for the right one */ -static int mt9m001_video_probe(struct soc_camera_link *icl, +static int mt9m001_video_probe(struct soc_camera_subdev_desc *ssdd, struct i2c_client *client) { struct mt9m001 *mt9m001 = to_mt9m001(client); @@ -505,11 +482,9 @@ static int mt9m001_video_probe(struct soc_camera_link *icl, switch (data) { case 0x8411: case 0x8421: - mt9m001->model = V4L2_IDENT_MT9M001C12ST; mt9m001->fmts = mt9m001_colour_fmts; break; case 0x8431: - mt9m001->model = V4L2_IDENT_MT9M001C12STM; mt9m001->fmts = mt9m001_monochrome_fmts; break; default: @@ -526,8 +501,8 @@ static int mt9m001_video_probe(struct soc_camera_link *icl, * The platform may support different bus widths due to * different routing of the data lines. */ - if (icl->query_bus_param) - flags = icl->query_bus_param(icl); + if (ssdd->query_bus_param) + flags = ssdd->query_bus_param(ssdd); else flags = SOCAM_DATAWIDTH_10; @@ -558,10 +533,10 @@ done: return ret; } -static void mt9m001_video_remove(struct soc_camera_link *icl) +static void mt9m001_video_remove(struct soc_camera_subdev_desc *ssdd) { - if (icl->free_bus) - icl->free_bus(icl); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); } static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) @@ -580,7 +555,6 @@ static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = { }; static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { - .g_chip_ident = mt9m001_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9m001_g_register, .s_register = mt9m001_s_register, @@ -605,14 +579,14 @@ static int mt9m001_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); /* MT9M001 has all capture_format parameters fixed */ cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -621,12 +595,12 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { const struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct mt9m001 *mt9m001 = to_mt9m001(client); unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample; - if (icl->set_bus_param) - return icl->set_bus_param(icl, 1 << (bps - 1)); + if (ssdd->set_bus_param) + return ssdd->set_bus_param(ssdd, 1 << (bps - 1)); /* * Without board specific bus width settings we only support the @@ -663,10 +637,10 @@ static int mt9m001_probe(struct i2c_client *client, { struct mt9m001 *mt9m001; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "MT9M001 driver needs platform data\n"); return -EINVAL; } @@ -677,7 +651,7 @@ static int mt9m001_probe(struct i2c_client *client, return -EIO; } - mt9m001 = kzalloc(sizeof(struct mt9m001), GFP_KERNEL); + mt9m001 = devm_kzalloc(&client->dev, sizeof(struct mt9m001), GFP_KERNEL); if (!mt9m001) return -ENOMEM; @@ -697,12 +671,9 @@ static int mt9m001_probe(struct i2c_client *client, &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_AUTO); mt9m001->subdev.ctrl_handler = &mt9m001->hdl; - if (mt9m001->hdl.error) { - int err = mt9m001->hdl.error; + if (mt9m001->hdl.error) + return mt9m001->hdl.error; - kfree(mt9m001); - return err; - } v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure, V4L2_EXPOSURE_MANUAL, true); @@ -713,10 +684,17 @@ static int mt9m001_probe(struct i2c_client *client, mt9m001->rect.width = MT9M001_MAX_WIDTH; mt9m001->rect.height = MT9M001_MAX_HEIGHT; - ret = mt9m001_video_probe(icl, client); + mt9m001->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(mt9m001->clk)) { + ret = PTR_ERR(mt9m001->clk); + goto eclkget; + } + + ret = mt9m001_video_probe(ssdd, client); if (ret) { + v4l2_clk_put(mt9m001->clk); +eclkget: v4l2_ctrl_handler_free(&mt9m001->hdl); - kfree(mt9m001); } return ret; @@ -725,12 +703,12 @@ static int mt9m001_probe(struct i2c_client *client, static int mt9m001_remove(struct i2c_client *client) { struct mt9m001 *mt9m001 = to_mt9m001(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + v4l2_clk_put(mt9m001->clk); v4l2_device_unregister_subdev(&mt9m001->subdev); v4l2_ctrl_handler_free(&mt9m001->hdl); - mt9m001_video_remove(icl); - kfree(mt9m001); + mt9m001_video_remove(ssdd); return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index 62fd94af599..ccf59406a17 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -17,14 +17,15 @@ #include <linux/module.h> #include <media/soc_camera.h> +#include <media/v4l2-clk.h> #include <media/v4l2-common.h> #include <media/v4l2-ctrls.h> -#include <media/v4l2-chip-ident.h> /* * MT9M111, MT9M112 and MT9M131: * i2c address is 0x48 or 0x5d (depending on SADDR pin) - * The platform has to define i2c_board_info and call i2c_register_board_info() + * The platform has to define struct i2c_board_info objects and link to them + * from struct soc_camera_host_desc */ /* @@ -204,12 +205,11 @@ struct mt9m111 { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; struct v4l2_ctrl *gain; - int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code - * from v4l2-chip-ident.h */ struct mt9m111_context *ctx; struct v4l2_rect rect; /* cropping rectangle */ - int width; /* output */ - int height; /* sizes */ + struct v4l2_clk *clk; + unsigned int width; /* output */ + unsigned int height; /* sizes */ struct mutex power_lock; /* lock to protect power_count */ int power_count; const struct mt9m111_datafmt *fmt; @@ -599,24 +599,6 @@ static int mt9m111_s_fmt(struct v4l2_subdev *sd, return ret; } -static int mt9m111_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = mt9m111->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m111_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -624,10 +606,8 @@ static int mt9m111_g_register(struct v4l2_subdev *sd, struct i2c_client *client = v4l2_get_subdevdata(sd); int val; - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + if (reg->reg > 0x2ff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; val = mt9m111_reg_read(client, reg->reg); reg->size = 2; @@ -640,16 +620,13 @@ static int mt9m111_g_register(struct v4l2_subdev *sd, } static int mt9m111_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + if (reg->reg > 0x2ff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - if (mt9m111_reg_write(client, reg->reg, reg->val) < 0) return -EIO; @@ -700,11 +677,11 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain) return reg_write(GLOBAL_GAIN, val); } -static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on) +static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int val) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); - if (on) + if (val == V4L2_EXPOSURE_AUTO) return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); } @@ -784,8 +761,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111) struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); int ret; - /* Default HIGHPOWER context */ - mt9m111->ctx = &context_b; ret = mt9m111_enable(mt9m111); if (!ret) ret = mt9m111_reset(mt9m111); @@ -799,17 +774,17 @@ static int mt9m111_init(struct mt9m111 *mt9m111) static int mt9m111_power_on(struct mt9m111 *mt9m111) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - ret = soc_camera_power_on(&client->dev, icl); + ret = soc_camera_power_on(&client->dev, ssdd, mt9m111->clk); if (ret < 0) return ret; ret = mt9m111_resume(mt9m111); if (ret < 0) { dev_err(&client->dev, "Failed to resume the sensor: %d\n", ret); - soc_camera_power_off(&client->dev, icl); + soc_camera_power_off(&client->dev, ssdd, mt9m111->clk); } return ret; @@ -818,10 +793,10 @@ static int mt9m111_power_on(struct mt9m111 *mt9m111) static void mt9m111_power_off(struct mt9m111 *mt9m111) { struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); mt9m111_suspend(mt9m111); - soc_camera_power_off(&client->dev, icl); + soc_camera_power_off(&client->dev, ssdd, mt9m111->clk); } static int mt9m111_s_power(struct v4l2_subdev *sd, int on) @@ -857,7 +832,6 @@ static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = { }; static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { - .g_chip_ident = mt9m111_g_chip_ident, .s_power = mt9m111_s_power, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9m111_g_register, @@ -879,13 +853,13 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -924,12 +898,10 @@ static int mt9m111_video_probe(struct i2c_client *client) switch (data) { case 0x143a: /* MT9M111 or MT9M131 */ - mt9m111->model = V4L2_IDENT_MT9M111; dev_info(&client->dev, "Detected a MT9M111/MT9M131 chip ID %x\n", data); break; case 0x148c: /* MT9M112 */ - mt9m111->model = V4L2_IDENT_MT9M112; dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); break; default: @@ -956,10 +928,10 @@ static int mt9m111_probe(struct i2c_client *client, { struct mt9m111 *mt9m111; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "mt9m111: driver needs platform data\n"); return -EINVAL; } @@ -970,10 +942,17 @@ static int mt9m111_probe(struct i2c_client *client, return -EIO; } - mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL); + mt9m111 = devm_kzalloc(&client->dev, sizeof(struct mt9m111), GFP_KERNEL); if (!mt9m111) return -ENOMEM; + mt9m111->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(mt9m111->clk)) + return -EPROBE_DEFER; + + /* Default HIGHPOWER context */ + mt9m111->ctx = &context_b; + v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); v4l2_ctrl_handler_init(&mt9m111->hdl, 5); v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops, @@ -989,10 +968,8 @@ static int mt9m111_probe(struct i2c_client *client, V4L2_EXPOSURE_AUTO); mt9m111->subdev.ctrl_handler = &mt9m111->hdl; if (mt9m111->hdl.error) { - int err = mt9m111->hdl.error; - - kfree(mt9m111); - return err; + ret = mt9m111->hdl.error; + goto out_clkput; } /* Second stage probe - when a capture adapter is there */ @@ -1004,11 +981,25 @@ static int mt9m111_probe(struct i2c_client *client, mt9m111->lastpage = -1; mutex_init(&mt9m111->power_lock); + ret = soc_camera_power_init(&client->dev, ssdd); + if (ret < 0) + goto out_hdlfree; + ret = mt9m111_video_probe(client); - if (ret) { - v4l2_ctrl_handler_free(&mt9m111->hdl); - kfree(mt9m111); - } + if (ret < 0) + goto out_hdlfree; + + mt9m111->subdev.dev = &client->dev; + ret = v4l2_async_register_subdev(&mt9m111->subdev); + if (ret < 0) + goto out_hdlfree; + + return 0; + +out_hdlfree: + v4l2_ctrl_handler_free(&mt9m111->hdl); +out_clkput: + v4l2_clk_put(mt9m111->clk); return ret; } @@ -1017,9 +1008,10 @@ static int mt9m111_remove(struct i2c_client *client) { struct mt9m111 *mt9m111 = to_mt9m111(client); + v4l2_async_unregister_subdev(&mt9m111->subdev); + v4l2_clk_put(mt9m111->clk); v4l2_device_unregister_subdev(&mt9m111->subdev); v4l2_ctrl_handler_free(&mt9m111->hdl); - kfree(mt9m111); return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 40800b10a08..ee7bb0ffcec 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -18,7 +18,7 @@ #include <linux/module.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> #include <media/v4l2-ctrls.h> @@ -31,8 +31,8 @@ /* * mt9t031 i2c address 0x5d - * The platform has to define i2c_board_info and link to it from - * struct soc_camera_link + * The platform has to define struct i2c_board_info objects and link to them + * from struct soc_camera_host_desc */ /* mt9t031 selected register addresses */ @@ -76,7 +76,7 @@ struct mt9t031 { struct v4l2_ctrl *exposure; }; struct v4l2_rect rect; /* Sensor window */ - int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ + struct v4l2_clk *clk; u16 xskip; u16 yskip; unsigned int total_h; @@ -391,36 +391,16 @@ static int mt9t031_try_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9t031_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9t031 *mt9t031 = to_mt9t031(client); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = mt9t031->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9t031_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - + reg->size = 1; reg->val = reg_read(client, reg->reg); if (reg->val > 0xffff) @@ -430,16 +410,13 @@ static int mt9t031_g_register(struct v4l2_subdev *sd, } static int mt9t031_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - if (reg_write(client, reg->reg, reg->val) < 0) return -EIO; @@ -595,7 +572,7 @@ static int mt9t031_runtime_resume(struct device *dev) return 0; } -static struct dev_pm_ops mt9t031_dev_pm_ops = { +static const struct dev_pm_ops mt9t031_dev_pm_ops = { .runtime_suspend = mt9t031_runtime_suspend, .runtime_resume = mt9t031_runtime_resume, }; @@ -608,18 +585,22 @@ static struct device_type mt9t031_dev_type = { static int mt9t031_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct video_device *vdev = soc_camera_i2c_to_vdev(client); + struct mt9t031 *mt9t031 = to_mt9t031(client); int ret; if (on) { - ret = soc_camera_power_on(&client->dev, icl); + ret = soc_camera_power_on(&client->dev, ssdd, mt9t031->clk); if (ret < 0) return ret; - vdev->dev.type = &mt9t031_dev_type; + if (vdev) + /* Not needed during probing, when vdev isn't available yet */ + vdev->dev.type = &mt9t031_dev_type; } else { - vdev->dev.type = NULL; - soc_camera_power_off(&client->dev, icl); + if (vdev) + vdev->dev.type = NULL; + soc_camera_power_off(&client->dev, ssdd, mt9t031->clk); } return 0; @@ -650,7 +631,6 @@ static int mt9t031_video_probe(struct i2c_client *client) switch (data) { case 0x1621: - mt9t031->model = V4L2_IDENT_MT9T031; break; default: dev_err(&client->dev, @@ -685,7 +665,6 @@ static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = { }; static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { - .g_chip_ident = mt9t031_g_chip_ident, .s_power = mt9t031_s_power, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9t031_g_register, @@ -707,13 +686,13 @@ static int mt9t031_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -722,9 +701,9 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); - if (soc_camera_apply_board_flags(icl, cfg) & + if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_FALLING) return reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000); else @@ -758,11 +737,11 @@ static int mt9t031_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9t031 *mt9t031; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "MT9T031 driver needs platform data\n"); return -EINVAL; } @@ -773,7 +752,7 @@ static int mt9t031_probe(struct i2c_client *client, return -EIO; } - mt9t031 = kzalloc(sizeof(struct mt9t031), GFP_KERNEL); + mt9t031 = devm_kzalloc(&client->dev, sizeof(struct mt9t031), GFP_KERNEL); if (!mt9t031) return -ENOMEM; @@ -797,12 +776,9 @@ static int mt9t031_probe(struct i2c_client *client, V4L2_CID_EXPOSURE, 1, 255, 1, 255); mt9t031->subdev.ctrl_handler = &mt9t031->hdl; - if (mt9t031->hdl.error) { - int err = mt9t031->hdl.error; + if (mt9t031->hdl.error) + return mt9t031->hdl.error; - kfree(mt9t031); - return err; - } v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure, V4L2_EXPOSURE_MANUAL, true); @@ -815,10 +791,17 @@ static int mt9t031_probe(struct i2c_client *client, mt9t031->xskip = 1; mt9t031->yskip = 1; + mt9t031->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(mt9t031->clk)) { + ret = PTR_ERR(mt9t031->clk); + goto eclkget; + } + ret = mt9t031_video_probe(client); if (ret) { + v4l2_clk_put(mt9t031->clk); +eclkget: v4l2_ctrl_handler_free(&mt9t031->hdl); - kfree(mt9t031); } return ret; @@ -828,9 +811,9 @@ static int mt9t031_remove(struct i2c_client *client) { struct mt9t031 *mt9t031 = to_mt9t031(client); + v4l2_clk_put(mt9t031->clk); v4l2_device_unregister_subdev(&mt9t031->subdev); v4l2_ctrl_handler_free(&mt9t031->hdl); - kfree(mt9t031); return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index de7cd836b0a..46f431a1378 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -27,7 +27,7 @@ #include <media/mt9t112.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-common.h> /* you can check PLL/clock info */ @@ -90,8 +90,9 @@ struct mt9t112_priv { struct mt9t112_camera_info *info; struct i2c_client *client; struct v4l2_rect frame; + struct v4l2_clk *clk; const struct mt9t112_format *format; - int model; + int num_formats; u32 flags; /* for flags */ #define INIT_DONE (1 << 0) @@ -737,17 +738,6 @@ static int mt9t112_init_camera(const struct i2c_client *client) /************************************************************************ v4l2_subdev_core_ops ************************************************************************/ -static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9t112_priv *priv = to_mt9t112(client); - - id->ident = priv->model; - id->revision = 0; - - return 0; -} #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9t112_g_register(struct v4l2_subdev *sd, @@ -765,7 +755,7 @@ static int mt9t112_g_register(struct v4l2_subdev *sd, } static int mt9t112_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); int ret; @@ -779,13 +769,13 @@ static int mt9t112_s_register(struct v4l2_subdev *sd, static int mt9t112_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9t112_priv *priv = to_mt9t112(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { - .g_chip_ident = mt9t112_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9t112_g_register, .s_register = mt9t112_s_register, @@ -859,11 +849,11 @@ static int mt9t112_set_params(struct mt9t112_priv *priv, /* * get color format */ - for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++) + for (i = 0; i < priv->num_formats; i++) if (mt9t112_cfmts[i].code == code) break; - if (i == ARRAY_SIZE(mt9t112_cfmts)) + if (i == priv->num_formats) return -EINVAL; priv->frame = *rect; @@ -955,14 +945,16 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd, static int mt9t112_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9t112_priv *priv = to_mt9t112(client); unsigned int top, left; int i; - for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++) + for (i = 0; i < priv->num_formats; i++) if (mt9t112_cfmts[i].code == mf->code) break; - if (i == ARRAY_SIZE(mt9t112_cfmts)) { + if (i == priv->num_formats) { mf->code = V4L2_MBUS_FMT_UYVY8_2X8; mf->colorspace = V4L2_COLORSPACE_JPEG; } else { @@ -979,7 +971,10 @@ static int mt9t112_try_fmt(struct v4l2_subdev *sd, static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index, enum v4l2_mbus_pixelcode *code) { - if (index >= ARRAY_SIZE(mt9t112_cfmts)) + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9t112_priv *priv = to_mt9t112(client); + + if (index >= priv->num_formats) return -EINVAL; *code = mt9t112_cfmts[index].code; @@ -991,13 +986,13 @@ static int mt9t112_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -1006,10 +1001,10 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct mt9t112_priv *priv = to_mt9t112(client); - if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING) + if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING) priv->flags |= PCLK_RISING; return 0; @@ -1055,11 +1050,11 @@ static int mt9t112_camera_probe(struct i2c_client *client) switch (chipid) { case 0x2680: devname = "mt9t111"; - priv->model = V4L2_IDENT_MT9T111; + priv->num_formats = 1; break; case 0x2682: devname = "mt9t112"; - priv->model = V4L2_IDENT_MT9T112; + priv->num_formats = ARRAY_SIZE(mt9t112_cfmts); break; default: dev_err(&client->dev, "Product ID error %04x\n", chipid); @@ -1078,7 +1073,7 @@ static int mt9t112_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9t112_priv *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct v4l2_rect rect = { .width = VGA_WIDTH, .height = VGA_HEIGHT, @@ -1087,27 +1082,30 @@ static int mt9t112_probe(struct i2c_client *client, }; int ret; - if (!icl || !icl->priv) { + if (!ssdd || !ssdd->drv_priv) { dev_err(&client->dev, "mt9t112: missing platform data!\n"); return -EINVAL; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->info = icl->priv; + priv->info = ssdd->drv_priv; v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + ret = mt9t112_camera_probe(client); - if (ret) { - kfree(priv); - return ret; - } /* Cannot fail: using the default supported pixel code */ - mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); + if (!ret) + mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); + else + v4l2_clk_put(priv->clk); return ret; } @@ -1116,7 +1114,7 @@ static int mt9t112_remove(struct i2c_client *client) { struct mt9t112_priv *priv = to_mt9t112(client); - kfree(priv); + v4l2_clk_put(priv->clk); return 0; } diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index d40a8858be0..f9f95f815b1 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -19,13 +19,13 @@ #include <media/soc_camera.h> #include <media/soc_mediabus.h> #include <media/v4l2-subdev.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-ctrls.h> /* * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c * The platform has to define struct i2c_board_info objects and link to them - * from struct soc_camera_link + * from struct soc_camera_host_desc */ static char *sensor_type; @@ -133,6 +133,11 @@ static const struct mt9v02x_register mt9v024_register = { .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV, }; +enum mt9v022_model { + MT9V022IX7ATM, + MT9V022IX7ATC, +}; + struct mt9v022 { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; @@ -149,11 +154,12 @@ struct mt9v022 { struct v4l2_ctrl *hblank; struct v4l2_ctrl *vblank; struct v4l2_rect rect; /* Sensor window */ + struct v4l2_clk *clk; const struct mt9v022_datafmt *fmt; const struct mt9v022_datafmt *fmts; const struct mt9v02x_register *reg; int num_fmts; - int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ + enum mt9v022_model model; u16 chip_control; u16 chip_version; unsigned short y_skip_top; /* Lines to skip at the top */ @@ -275,6 +281,7 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); struct v4l2_rect rect = a->c; + int min_row, min_blank; int ret; /* Bayer format - even size lengths */ @@ -310,13 +317,21 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) ret = reg_write(client, MT9V022_COLUMN_START, rect.left); if (!ret) ret = reg_write(client, MT9V022_ROW_START, rect.top); + /* + * mt9v022: min total row time is 660 columns, min blanking is 43 + * mt9v024: min total row time is 690 columns, min blanking is 61 + */ + if (is_mt9v024(mt9v022->chip_version)) { + min_row = 690; + min_blank = 61; + } else { + min_row = 660; + min_blank = 43; + } if (!ret) - /* - * Default 94, Phytec driver says: - * "width + horizontal blank >= 660" - */ ret = v4l2_ctrl_s_ctrl(mt9v022->hblank, - rect.width > 660 - 43 ? 43 : 660 - rect.width); + rect.width > min_row - min_blank ? + min_blank : min_row - rect.width); if (!ret) ret = v4l2_ctrl_s_ctrl(mt9v022->vblank, 45); if (!ret) @@ -397,12 +412,12 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, switch (mf->code) { case V4L2_MBUS_FMT_Y8_1X8: case V4L2_MBUS_FMT_Y10_1X10: - if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) + if (mt9v022->model != MT9V022IX7ATM) return -EINVAL; break; case V4L2_MBUS_FMT_SBGGR8_1X8: case V4L2_MBUS_FMT_SBGGR10_1X10: - if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) + if (mt9v022->model != MT9V022IX7ATC) return -EINVAL; break; default: @@ -448,36 +463,15 @@ static int mt9v022_try_fmt(struct v4l2_subdev *sd, return 0; } -static int mt9v022_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct mt9v022 *mt9v022 = to_mt9v022(client); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = mt9v022->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9v022_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - reg->size = 2; reg->val = reg_read(client, reg->reg); @@ -488,16 +482,13 @@ static int mt9v022_g_register(struct v4l2_subdev *sd, } static int mt9v022_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) + if (reg->reg > 0xff) return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - if (reg_write(client, reg->reg, reg->val) < 0) return -EIO; @@ -508,9 +499,10 @@ static int mt9v022_s_register(struct v4l2_subdev *sd, static int mt9v022_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct mt9v022 *mt9v022 = to_mt9v022(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, mt9v022->clk, on); } static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl) @@ -655,7 +647,7 @@ static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl) static int mt9v022_video_probe(struct i2c_client *client) { struct mt9v022 *mt9v022 = to_mt9v022(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); s32 data; int ret; unsigned long flags; @@ -697,11 +689,11 @@ static int mt9v022_video_probe(struct i2c_client *client) if (sensor_type && (!strcmp("colour", sensor_type) || !strcmp("color", sensor_type))) { ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11); - mt9v022->model = V4L2_IDENT_MT9V022IX7ATC; + mt9v022->model = MT9V022IX7ATC; mt9v022->fmts = mt9v022_colour_fmts; } else { ret = reg_write(client, MT9V022_PIXEL_OPERATION_MODE, 0x11); - mt9v022->model = V4L2_IDENT_MT9V022IX7ATM; + mt9v022->model = MT9V022IX7ATM; mt9v022->fmts = mt9v022_monochrome_fmts; } @@ -715,8 +707,8 @@ static int mt9v022_video_probe(struct i2c_client *client) * The platform may support different bus widths due to * different routing of the data lines. */ - if (icl->query_bus_param) - flags = icl->query_bus_param(icl); + if (ssdd->query_bus_param) + flags = ssdd->query_bus_param(ssdd); else flags = SOCAM_DATAWIDTH_10; @@ -731,7 +723,7 @@ static int mt9v022_video_probe(struct i2c_client *client) mt9v022->fmt = &mt9v022->fmts[0]; dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", - data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? + data, mt9v022->model == MT9V022IX7ATM ? "monochrome" : "colour"); ret = mt9v022_init(client); @@ -759,7 +751,6 @@ static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = { }; static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { - .g_chip_ident = mt9v022_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9v022_g_register, .s_register = mt9v022_s_register, @@ -784,7 +775,7 @@ static int mt9v022_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | @@ -792,7 +783,7 @@ static int mt9v022_g_mbus_config(struct v4l2_subdev *sd, V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -801,15 +792,15 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct mt9v022 *mt9v022 = to_mt9v022(client); - unsigned long flags = soc_camera_apply_board_flags(icl, cfg); + unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg); unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample; int ret; u16 pixclk = 0; - if (icl->set_bus_param) { - ret = icl->set_bus_param(icl, 1 << (bps - 1)); + if (ssdd->set_bus_param) { + ret = ssdd->set_bus_param(ssdd, 1 << (bps - 1)); if (ret) return ret; } else if (bps != 10) { @@ -873,12 +864,12 @@ static int mt9v022_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct mt9v022 *mt9v022; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct mt9v022_platform_data *pdata = icl->priv; + struct mt9v022_platform_data *pdata; int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "MT9V022 driver needs platform data\n"); return -EINVAL; } @@ -889,10 +880,11 @@ static int mt9v022_probe(struct i2c_client *client, return -EIO; } - mt9v022 = kzalloc(sizeof(struct mt9v022), GFP_KERNEL); + mt9v022 = devm_kzalloc(&client->dev, sizeof(struct mt9v022), GFP_KERNEL); if (!mt9v022) return -ENOMEM; + pdata = ssdd->drv_priv; v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops); v4l2_ctrl_handler_init(&mt9v022->hdl, 6); v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops, @@ -929,7 +921,6 @@ static int mt9v022_probe(struct i2c_client *client, int err = mt9v022->hdl.error; dev_err(&client->dev, "control initialisation err %d\n", err); - kfree(mt9v022); return err; } v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure, @@ -948,10 +939,17 @@ static int mt9v022_probe(struct i2c_client *client, mt9v022->rect.width = MT9V022_MAX_WIDTH; mt9v022->rect.height = MT9V022_MAX_HEIGHT; + mt9v022->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(mt9v022->clk)) { + ret = PTR_ERR(mt9v022->clk); + goto eclkget; + } + ret = mt9v022_video_probe(client); if (ret) { + v4l2_clk_put(mt9v022->clk); +eclkget: v4l2_ctrl_handler_free(&mt9v022->hdl); - kfree(mt9v022); } return ret; @@ -960,13 +958,13 @@ static int mt9v022_probe(struct i2c_client *client, static int mt9v022_remove(struct i2c_client *client) { struct mt9v022 *mt9v022 = to_mt9v022(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + v4l2_clk_put(mt9v022->clk); v4l2_device_unregister_subdev(&mt9v022->subdev); - if (icl->free_bus) - icl->free_bus(icl); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); v4l2_ctrl_handler_free(&mt9v022->hdl); - kfree(mt9v022); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 66698a83bda..6c6b1c3b45e 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -22,7 +22,7 @@ #include <linux/videodev2.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> #include <media/v4l2-ctrls.h> @@ -303,8 +303,8 @@ struct ov2640_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; enum v4l2_mbus_pixelcode cfmt_code; + struct v4l2_clk *clk; const struct ov2640_win_size *win; - int model; }; /* @@ -723,18 +723,6 @@ static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } -static int ov2640_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov2640_priv *priv = to_ov2640(client); - - id->ident = priv->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov2640_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -756,7 +744,7 @@ static int ov2640_g_register(struct v4l2_subdev *sd, } static int ov2640_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -771,9 +759,10 @@ static int ov2640_s_register(struct v4l2_subdev *sd, static int ov2640_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov2640_priv *priv = to_ov2640(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } /* Select the nearest higher resolution for capture */ @@ -1009,7 +998,6 @@ static int ov2640_video_probe(struct i2c_client *client) switch (VERSION(pid, ver)) { case PID_OV2640: devname = "ov2640"; - priv->model = V4L2_IDENT_OV2640; break; default: dev_err(&client->dev, @@ -1034,7 +1022,6 @@ static const struct v4l2_ctrl_ops ov2640_ctrl_ops = { }; static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { - .g_chip_ident = ov2640_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov2640_g_register, .s_register = ov2640_s_register, @@ -1046,13 +1033,13 @@ static int ov2640_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -1080,11 +1067,11 @@ static int ov2640_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov2640_priv *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret; - if (!icl) { + if (!ssdd) { dev_err(&adapter->dev, "OV2640: Missing platform_data for driver\n"); return -EINVAL; @@ -1096,7 +1083,7 @@ static int ov2640_probe(struct i2c_client *client, return -EIO; } - priv = kzalloc(sizeof(struct ov2640_priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(struct ov2640_priv), GFP_KERNEL); if (!priv) { dev_err(&adapter->dev, "Failed to allocate memory for private data!\n"); @@ -1110,17 +1097,20 @@ static int ov2640_probe(struct i2c_client *client, v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) { - int err = priv->hdl.error; + if (priv->hdl.error) + return priv->hdl.error; - kfree(priv); - return err; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; } ret = ov2640_video_probe(client); if (ret) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); } else { dev_info(&adapter->dev, "OV2640 Probed\n"); } @@ -1132,9 +1122,9 @@ static int ov2640_remove(struct i2c_client *client) { struct ov2640_priv *priv = to_ov2640(client); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index 8577e0cfb7f..d2daa6a8f27 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -24,7 +24,7 @@ #include <linux/v4l2-mediabus.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> /* OV5642 registers */ @@ -610,6 +610,7 @@ struct ov5642 { struct v4l2_subdev subdev; const struct ov5642_datafmt *fmt; struct v4l2_rect crop_rect; + struct v4l2_clk *clk; /* blanking information */ int total_width; @@ -641,7 +642,7 @@ static const struct ov5642_datafmt static int reg_read(struct i2c_client *client, u16 reg, u8 *val) { int ret; - /* We have 16-bit i2c addresses - care for endianess */ + /* We have 16-bit i2c addresses - care for endianness */ unsigned char data[2] = { reg >> 8, reg & 0xff }; ret = i2c_master_send(client, data, 2); @@ -708,7 +709,7 @@ static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register return ret; } -static int ov5642_set_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) +static int ov5642_set_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -848,23 +849,6 @@ static int ov5642_enum_fmt(struct v4l2_subdev *sd, unsigned int index, return 0; } -static int ov5642_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = V4L2_IDENT_OV5642; - id->revision = 0; - - return 0; -} - static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -934,13 +918,14 @@ static int ov5642_g_mbus_config(struct v4l2_subdev *sd, static int ov5642_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov5642 *priv = to_ov5642(client); int ret; if (!on) - return soc_camera_power_off(&client->dev, icl); + return soc_camera_power_off(&client->dev, ssdd, priv->clk); - ret = soc_camera_power_on(&client->dev, icl); + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); if (ret < 0) return ret; @@ -966,7 +951,6 @@ static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { .s_power = ov5642_s_power, - .g_chip_ident = ov5642_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov5642_get_register, .s_register = ov5642_set_register, @@ -1020,15 +1004,15 @@ static int ov5642_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov5642 *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "OV5642: missing platform data!\n"); return -EINVAL; } - priv = kzalloc(sizeof(struct ov5642), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(struct ov5642), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1043,25 +1027,25 @@ static int ov5642_probe(struct i2c_client *client, priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH; priv->total_height = BLANKING_MIN_HEIGHT; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + ret = ov5642_video_probe(client); if (ret < 0) - goto error; - - return 0; + v4l2_clk_put(priv->clk); -error: - kfree(priv); return ret; } static int ov5642_remove(struct i2c_client *client) { + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct ov5642 *priv = to_ov5642(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); - if (icl->free_bus) - icl->free_bus(icl); - kfree(priv); + v4l2_clk_put(priv->clk); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index e87feb0881e..ab01598ec83 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -32,7 +32,7 @@ #include <linux/module.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-ctrls.h> /* Register definitions */ @@ -196,6 +196,7 @@ struct ov6650 { struct v4l2_ctrl *blue; struct v4l2_ctrl *red; }; + struct v4l2_clk *clk; bool half_scale; /* scale down output by 2 */ struct v4l2_rect rect; /* sensor cropping window */ unsigned long pclk_limit; /* from host */ @@ -390,16 +391,6 @@ static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } -/* Get chip identification */ -static int ov6650_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - id->ident = V4L2_IDENT_OV6650; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov6650_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -421,7 +412,7 @@ static int ov6650_get_register(struct v4l2_subdev *sd, } static int ov6650_set_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -435,9 +426,10 @@ static int ov6650_set_register(struct v4l2_subdev *sd, static int ov6650_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov6650 *priv = to_ov6650(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) @@ -879,7 +871,6 @@ static const struct v4l2_ctrl_ops ov6550_ctrl_ops = { }; static struct v4l2_subdev_core_ops ov6650_core_ops = { - .g_chip_ident = ov6650_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov6650_get_register, .s_register = ov6650_set_register, @@ -892,7 +883,7 @@ static int ov6650_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | @@ -900,7 +891,7 @@ static int ov6650_g_mbus_config(struct v4l2_subdev *sd, V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -910,8 +901,8 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); - unsigned long flags = soc_camera_apply_board_flags(icl, cfg); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg); int ret; if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) @@ -963,15 +954,15 @@ static int ov6650_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov6650 *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "Missing platform_data for driver\n"); return -EINVAL; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&client->dev, "Failed to allocate memory for private data!\n"); @@ -1009,12 +1000,9 @@ static int ov6650_probe(struct i2c_client *client, V4L2_CID_GAMMA, 0, 0xff, 1, 0x12); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) { - int err = priv->hdl.error; + if (priv->hdl.error) + return priv->hdl.error; - kfree(priv); - return err; - } v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true); v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true); v4l2_ctrl_auto_cluster(2, &priv->autoexposure, @@ -1028,10 +1016,17 @@ static int ov6650_probe(struct i2c_client *client, priv->code = V4L2_MBUS_FMT_YUYV8_2X8; priv->colorspace = V4L2_COLORSPACE_JPEG; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; + } + ret = ov6650_video_probe(client); if (ret) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); } return ret; @@ -1041,9 +1036,9 @@ static int ov6650_remove(struct i2c_client *client) { struct ov6650 *priv = to_ov6650(client); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index e4a10751894..7f2b3c8926a 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -26,8 +26,8 @@ #include <media/ov772x.h> #include <media/soc_camera.h> +#include <media/v4l2-clk.h> #include <media/v4l2-ctrls.h> -#include <media/v4l2-chip-ident.h> #include <media/v4l2-subdev.h> /* @@ -396,10 +396,10 @@ struct ov772x_win_size { struct ov772x_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; struct ov772x_camera_info *info; const struct ov772x_color_format *cfmt; const struct ov772x_win_size *win; - int model; unsigned short flag_vflip:1; unsigned short flag_hflip:1; /* band_filter = COM8[5] ? 256 - BDBASE : 0 */ @@ -620,17 +620,6 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } -static int ov772x_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct ov772x_priv *priv = to_ov772x(sd); - - id->ident = priv->model; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov772x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -652,7 +641,7 @@ static int ov772x_g_register(struct v4l2_subdev *sd, } static int ov772x_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -667,9 +656,10 @@ static int ov772x_s_register(struct v4l2_subdev *sd, static int ov772x_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov772x_priv *priv = to_ov772x(sd); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height) @@ -965,11 +955,9 @@ static int ov772x_video_probe(struct ov772x_priv *priv) switch (VERSION(pid, ver)) { case OV7720: devname = "ov7720"; - priv->model = V4L2_IDENT_OV7720; break; case OV7725: devname = "ov7725"; - priv->model = V4L2_IDENT_OV7725; break; default: dev_err(&client->dev, @@ -997,7 +985,6 @@ static const struct v4l2_ctrl_ops ov772x_ctrl_ops = { }; static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { - .g_chip_ident = ov772x_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov772x_g_register, .s_register = ov772x_s_register, @@ -1019,13 +1006,13 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -1054,11 +1041,11 @@ static int ov772x_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov772x_priv *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int ret; - if (!icl || !icl->priv) { + if (!ssdd || !ssdd->drv_priv) { dev_err(&client->dev, "OV772X: missing platform data!\n"); return -EINVAL; } @@ -1070,11 +1057,11 @@ static int ov772x_probe(struct i2c_client *client, return -EIO; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->info = icl->priv; + priv->info = ssdd->drv_priv; v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); v4l2_ctrl_handler_init(&priv->hdl, 3); @@ -1085,23 +1072,25 @@ static int ov772x_probe(struct i2c_client *client, v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops, V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) { - ret = priv->hdl.error; - goto done; + if (priv->hdl.error) + return priv->hdl.error; + + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; } ret = ov772x_video_probe(priv); - if (ret < 0) - goto done; - - priv->cfmt = &ov772x_cfmts[0]; - priv->win = &ov772x_win_sizes[0]; - -done: - if (ret) { + if (ret < 0) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); + } else { + priv->cfmt = &ov772x_cfmts[0]; + priv->win = &ov772x_win_sizes[0]; } + return ret; } @@ -1109,9 +1098,9 @@ static int ov772x_remove(struct i2c_client *client) { struct ov772x_priv *priv = to_ov772x(i2c_get_clientdata(client)); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index b323684eaf7..bc74224503e 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -28,7 +28,7 @@ #include <linux/videodev2.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-common.h> #include <media/v4l2-ctrls.h> @@ -61,7 +61,7 @@ static const struct ov9640_reg ov9640_regs_dflt[] = { /* Configurations * NOTE: for YUV, alter the following registers: - * COM12 |= OV9640_COM12_YUV_AVG + * COM12 |= OV9640_COM12_YUV_AVG * * for RGB, alter the following registers: * COM7 |= OV9640_COM7_RGB @@ -287,18 +287,6 @@ static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl) return -EINVAL; } -/* Get chip identification */ -static int ov9640_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct ov9640_priv *priv = to_ov9640_sensor(sd); - - id->ident = priv->model; - id->revision = priv->revision; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov9640_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -322,7 +310,7 @@ static int ov9640_get_register(struct v4l2_subdev *sd, } static int ov9640_set_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -336,9 +324,10 @@ static int ov9640_set_register(struct v4l2_subdev *sd, static int ov9640_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct ov9640_priv *priv = to_ov9640_sensor(sd); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } /* select nearest higher resolution for capture */ @@ -382,7 +371,7 @@ static void ov9640_alter_regs(enum v4l2_mbus_pixelcode code, alt->com13 = OV9640_COM13_RGB_AVG; alt->com15 = OV9640_COM15_RGB_565; break; - }; + } } /* Setup registers according to resolution and color encoding */ @@ -615,12 +604,10 @@ static int ov9640_video_probe(struct i2c_client *client) switch (VERSION(pid, ver)) { case OV9640_V2: devname = "ov9640"; - priv->model = V4L2_IDENT_OV9640; priv->revision = 2; break; case OV9640_V3: devname = "ov9640"; - priv->model = V4L2_IDENT_OV9640; priv->revision = 3; break; default: @@ -644,7 +631,6 @@ static const struct v4l2_ctrl_ops ov9640_ctrl_ops = { }; static struct v4l2_subdev_core_ops ov9640_core_ops = { - .g_chip_ident = ov9640_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov9640_get_register, .s_register = ov9640_set_register, @@ -657,13 +643,13 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -690,15 +676,15 @@ static int ov9640_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov9640_priv *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "Missing platform_data for driver\n"); return -EINVAL; } - priv = kzalloc(sizeof(struct ov9640_priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(struct ov9640_priv), GFP_KERNEL); if (!priv) { dev_err(&client->dev, "Failed to allocate memory for private data!\n"); @@ -713,18 +699,20 @@ static int ov9640_probe(struct i2c_client *client, v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) { - int err = priv->hdl.error; + if (priv->hdl.error) + return priv->hdl.error; - kfree(priv); - return err; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; } ret = ov9640_video_probe(client); - if (ret) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); } return ret; @@ -735,9 +723,9 @@ static int ov9640_remove(struct i2c_client *client) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct ov9640_priv *priv = to_ov9640_sensor(sd); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); return 0; } diff --git a/drivers/media/i2c/soc_camera/ov9640.h b/drivers/media/i2c/soc_camera/ov9640.h index 6b33a972c83..65d13ff1753 100644 --- a/drivers/media/i2c/soc_camera/ov9640.h +++ b/drivers/media/i2c/soc_camera/ov9640.h @@ -199,6 +199,7 @@ struct ov9640_reg { struct ov9640_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; int model; int revision; diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index 7a55889e397..ea76863dfdb 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -17,7 +17,7 @@ #include <linux/v4l2-mediabus.h> #include <media/soc_camera.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-ctrls.h> #define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev) @@ -196,8 +196,8 @@ struct ov9740_reg { struct ov9740_priv { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; - int ident; u16 model; u8 revision; u8 manid; @@ -772,27 +772,15 @@ static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl) return 0; } -/* Get chip identification */ -static int ov9740_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct ov9740_priv *priv = to_ov9740(sd); - - id->ident = priv->ident; - id->revision = priv->revision; - - return 0; -} - static int ov9740_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct ov9740_priv *priv = to_ov9740(sd); int ret; if (on) { - ret = soc_camera_power_on(&client->dev, icl); + ret = soc_camera_power_on(&client->dev, ssdd, priv->clk); if (ret < 0) return ret; @@ -806,7 +794,7 @@ static int ov9740_s_power(struct v4l2_subdev *sd, int on) priv->current_enable = true; } - soc_camera_power_off(&client->dev, icl); + soc_camera_power_off(&client->dev, ssdd, priv->clk); } return 0; @@ -835,7 +823,7 @@ static int ov9740_get_register(struct v4l2_subdev *sd, } static int ov9740_set_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -887,8 +875,6 @@ static int ov9740_video_probe(struct i2c_client *client) goto done; } - priv->ident = V4L2_IDENT_OV9740; - dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, " "Manufacturer 0x%02x, SMIA Version 0x%02x\n", priv->model, priv->revision, priv->manid, priv->smiaver); @@ -905,13 +891,13 @@ static int ov9740_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -927,7 +913,6 @@ static struct v4l2_subdev_video_ops ov9740_video_ops = { }; static struct v4l2_subdev_core_ops ov9740_core_ops = { - .g_chip_ident = ov9740_g_chip_ident, .s_power = ov9740_s_power, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov9740_get_register, @@ -951,15 +936,15 @@ static int ov9740_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct ov9740_priv *priv; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); int ret; - if (!icl) { + if (!ssdd) { dev_err(&client->dev, "Missing platform_data for driver\n"); return -EINVAL; } - priv = kzalloc(sizeof(struct ov9740_priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(struct ov9740_priv), GFP_KERNEL); if (!priv) { dev_err(&client->dev, "Failed to allocate private data!\n"); return -ENOMEM; @@ -972,17 +957,20 @@ static int ov9740_probe(struct i2c_client *client, v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) { - int err = priv->hdl.error; + if (priv->hdl.error) + return priv->hdl.error; - kfree(priv); - return err; + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) { + ret = PTR_ERR(priv->clk); + goto eclkget; } ret = ov9740_video_probe(client); if (ret < 0) { + v4l2_clk_put(priv->clk); +eclkget: v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); } return ret; @@ -992,9 +980,9 @@ static int ov9740_remove(struct i2c_client *client) { struct ov9740_priv *priv = i2c_get_clientdata(client); + v4l2_clk_put(priv->clk); v4l2_device_unregister_subdev(&priv->subdev); v4l2_ctrl_handler_free(&priv->hdl); - kfree(priv); return 0; } diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index 02f0400051d..7e6d9784787 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -17,8 +17,8 @@ #include <media/rj54n1cb0c.h> #include <media/soc_camera.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> -#include <media/v4l2-chip-ident.h> #include <media/v4l2-ctrls.h> #define RJ54N1_DEV_CODE 0x0400 @@ -151,6 +151,7 @@ struct rj54n1_clock_div { struct rj54n1 { struct v4l2_subdev subdev; struct v4l2_ctrl_handler hdl; + struct v4l2_clk *clk; struct rj54n1_clock_div clk_div; const struct rj54n1_datafmt *fmt; struct v4l2_rect rect; /* Sensor window */ @@ -1120,37 +1121,16 @@ static int rj54n1_s_fmt(struct v4l2_subdev *sd, return 0; } -static int rj54n1_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) - return -EINVAL; - - if (id->match.addr != client->addr) - return -ENODEV; - - id->ident = V4L2_IDENT_RJ54N1CB0C; - id->revision = 0; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int rj54n1_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || - reg->reg < 0x400 || reg->reg > 0x1fff) + if (reg->reg < 0x400 || reg->reg > 0x1fff) /* Registers > 0x0800 are only available from Sharp support */ return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - reg->size = 1; reg->val = reg_read(client, reg->reg); @@ -1161,18 +1141,14 @@ static int rj54n1_g_register(struct v4l2_subdev *sd, } static int rj54n1_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || - reg->reg < 0x400 || reg->reg > 0x1fff) + if (reg->reg < 0x400 || reg->reg > 0x1fff) /* Registers >= 0x0800 are only available from Sharp support */ return -EINVAL; - if (reg->match.addr != client->addr) - return -ENODEV; - if (reg_write(client, reg->reg, reg->val) < 0) return -EIO; @@ -1183,9 +1159,10 @@ static int rj54n1_s_register(struct v4l2_subdev *sd, static int rj54n1_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct rj54n1 *rj54n1 = to_rj54n1(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, rj54n1->clk, on); } static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1233,7 +1210,6 @@ static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = { }; static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { - .g_chip_ident = rj54n1_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = rj54n1_g_register, .s_register = rj54n1_s_register, @@ -1245,14 +1221,14 @@ static int rj54n1_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -1261,10 +1237,10 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */ - if (soc_camera_apply_board_flags(icl, cfg) & + if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING) return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4); else @@ -1334,17 +1310,17 @@ static int rj54n1_probe(struct i2c_client *client, const struct i2c_device_id *did) { struct rj54n1 *rj54n1; - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct rj54n1_pdata *rj54n1_priv; int ret; - if (!icl || !icl->priv) { + if (!ssdd || !ssdd->drv_priv) { dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); return -EINVAL; } - rj54n1_priv = icl->priv; + rj54n1_priv = ssdd->drv_priv; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_warn(&adapter->dev, @@ -1352,7 +1328,7 @@ static int rj54n1_probe(struct i2c_client *client, return -EIO; } - rj54n1 = kzalloc(sizeof(struct rj54n1), GFP_KERNEL); + rj54n1 = devm_kzalloc(&client->dev, sizeof(struct rj54n1), GFP_KERNEL); if (!rj54n1) return -ENOMEM; @@ -1367,12 +1343,8 @@ static int rj54n1_probe(struct i2c_client *client, v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); rj54n1->subdev.ctrl_handler = &rj54n1->hdl; - if (rj54n1->hdl.error) { - int err = rj54n1->hdl.error; - - kfree(rj54n1); - return err; - } + if (rj54n1->hdl.error) + return rj54n1->hdl.error; rj54n1->clk_div = clk_div; rj54n1->rect.left = RJ54N1_COLUMN_SKIP; @@ -1386,10 +1358,17 @@ static int rj54n1_probe(struct i2c_client *client, rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) / (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1); + rj54n1->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(rj54n1->clk)) { + ret = PTR_ERR(rj54n1->clk); + goto eclkget; + } + ret = rj54n1_video_probe(client, rj54n1_priv); if (ret < 0) { + v4l2_clk_put(rj54n1->clk); +eclkget: v4l2_ctrl_handler_free(&rj54n1->hdl); - kfree(rj54n1); } return ret; @@ -1398,13 +1377,13 @@ static int rj54n1_probe(struct i2c_client *client, static int rj54n1_remove(struct i2c_client *client) { struct rj54n1 *rj54n1 = to_rj54n1(client); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + v4l2_clk_put(rj54n1->clk); v4l2_device_unregister_subdev(&rj54n1->subdev); - if (icl->free_bus) - icl->free_bus(icl); + if (ssdd->free_bus) + ssdd->free_bus(ssdd); v4l2_ctrl_handler_free(&rj54n1->hdl); - kfree(rj54n1); return 0; } diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 140716e71a1..416402eb4f8 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -27,7 +27,7 @@ #include <media/soc_camera.h> #include <media/tw9910.h> -#include <media/v4l2-chip-ident.h> +#include <media/v4l2-clk.h> #include <media/v4l2-subdev.h> #define GET_ID(val) ((val & 0xF8) >> 3) @@ -228,6 +228,7 @@ struct tw9910_scale_ctrl { struct tw9910_priv { struct v4l2_subdev subdev; + struct v4l2_clk *clk; struct tw9910_video_info *info; const struct tw9910_scale_ctrl *scale; v4l2_std_id norm; @@ -518,18 +519,6 @@ static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) return 0; } -static int tw9910_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *id) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct tw9910_priv *priv = to_tw9910(client); - - id->ident = V4L2_IDENT_TW9910; - id->revision = priv->revision; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int tw9910_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -540,6 +529,7 @@ static int tw9910_g_register(struct v4l2_subdev *sd, if (reg->reg > 0xff) return -EINVAL; + reg->size = 1; ret = i2c_smbus_read_byte_data(client, reg->reg); if (ret < 0) return ret; @@ -554,7 +544,7 @@ static int tw9910_g_register(struct v4l2_subdev *sd, } static int tw9910_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) + const struct v4l2_dbg_register *reg) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -569,9 +559,10 @@ static int tw9910_s_register(struct v4l2_subdev *sd, static int tw9910_s_power(struct v4l2_subdev *sd, int on) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + struct tw9910_priv *priv = to_tw9910(client); - return soc_camera_set_power(&client->dev, icl, on); + return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height) @@ -823,9 +814,6 @@ done: } static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { - .g_chip_ident = tw9910_g_chip_ident, - .s_std = tw9910_s_std, - .g_std = tw9910_g_std, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = tw9910_g_register, .s_register = tw9910_s_register, @@ -847,14 +835,14 @@ static int tw9910_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW | V4L2_MBUS_DATA_ACTIVE_HIGH; cfg->type = V4L2_MBUS_PARALLEL; - cfg->flags = soc_camera_apply_board_flags(icl, cfg); + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); return 0; } @@ -863,9 +851,9 @@ static int tw9910_s_mbus_config(struct v4l2_subdev *sd, const struct v4l2_mbus_config *cfg) { struct i2c_client *client = v4l2_get_subdevdata(sd); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); u8 val = VSSL_VVALID | HSSL_DVALID; - unsigned long flags = soc_camera_apply_board_flags(icl, cfg); + unsigned long flags = soc_camera_apply_board_flags(ssdd, cfg); /* * set OUTCTR1 @@ -882,7 +870,15 @@ static int tw9910_s_mbus_config(struct v4l2_subdev *sd, return i2c_smbus_write_byte_data(client, OUTCTR1, val); } +static int tw9910_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *norm) +{ + *norm = V4L2_STD_NTSC | V4L2_STD_PAL; + return 0; +} + static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { + .s_std = tw9910_s_std, + .g_std = tw9910_g_std, .s_stream = tw9910_s_stream, .g_mbus_fmt = tw9910_g_fmt, .s_mbus_fmt = tw9910_s_fmt, @@ -892,6 +888,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .enum_mbus_fmt = tw9910_enum_fmt, .g_mbus_config = tw9910_g_mbus_config, .s_mbus_config = tw9910_s_mbus_config, + .g_tvnorms = tw9910_g_tvnorms, }; static struct v4l2_subdev_ops tw9910_subdev_ops = { @@ -911,15 +908,15 @@ static int tw9910_probe(struct i2c_client *client, struct tw9910_video_info *info; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl = soc_camera_i2c_to_link(client); - int ret; + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); + int ret; - if (!icl || !icl->priv) { + if (!ssdd || !ssdd->drv_priv) { dev_err(&client->dev, "TW9910: missing platform data!\n"); return -EINVAL; } - info = icl->priv; + info = ssdd->drv_priv; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, @@ -928,7 +925,7 @@ static int tw9910_probe(struct i2c_client *client, return -EIO; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -936,9 +933,13 @@ static int tw9910_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); + priv->clk = v4l2_clk_get(&client->dev, "mclk"); + if (IS_ERR(priv->clk)) + return PTR_ERR(priv->clk); + ret = tw9910_video_probe(client); - if (ret) - kfree(priv); + if (ret < 0) + v4l2_clk_put(priv->clk); return ret; } @@ -946,8 +947,7 @@ static int tw9910_probe(struct i2c_client *client, static int tw9910_remove(struct i2c_client *client) { struct tw9910_priv *priv = to_tw9910(client); - - kfree(priv); + v4l2_clk_put(priv->clk); return 0; } |
