Dne 14.9.2018 v 14:59 Sakari Ailus napsal(a): > Hi Petr, > > Thanks for the patchset, and my apologies for reviewing it so late! > > I'm commenting this one but feel free to add patches to address the > comments. > Hi and thanks for the review. I would like to have this patch set to be as much as possible only a conversion from soc-camera, but I guess I can fix the error handling in probe and the missing newlines. For the enhanced functionality, I would like to have a new patch set after I'll patch the controller (pxa camera) on my testing platform. >> +/* Start/Stop streaming from the device */ >> +static int ov9640_s_stream(struct v4l2_subdev *sd, int enable) >> +{ >> + return 0; > > Doesn't the sensor provide any control over the streaming state? Just > wondering... > Before the PXA camera switch from soc-camera I've found some deficiencies in register settings so I'm planning to test them all. With the current state of vanilla I wouldn't be able to test the change. After the quick search in datasheet I wasn't able to find any (stream, capture, start) flag. It may be controlled by just setting the output format flags, but these registers are some of those I will be changing in the future. >> +static int ov9640_s_power(struct v4l2_subdev *sd, int on) >> +{ >> + struct i2c_client *client = v4l2_get_subdevdata(sd); >> + 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, ssdd, priv->clk, on); > > Runtime PM support would be nice --- but not needed in this set IMO. > If I remember correctly a suspend to mem will freeze the whole machine, so in the future :-/. >> +} >> + >> +/* select nearest higher resolution for capture */ >> +static void ov9640_res_roundup(u32 *width, u32 *height) >> +{ >> + int i; > > unsigned int > > Same for other loops where no negative values or test below zero are > needed (or where the value which is compared against is signed). > Just re-declaring: unsigned int i; ... OK >> + >> + cfg->try_fmt = *mf; > > Newline here? > >> + return 0; >> +} >> + >> +static int ov9640_enum_mbus_code(struct v4l2_subdev *sd, >> + struct v4l2_subdev_pad_config *cfg, >> + struct v4l2_subdev_mbus_code_enum *code) >> +{ >> + if (code->pad || code->index >= ARRAY_SIZE(ov9640_codes)) >> + return -EINVAL; >> + >> + code->code = ov9640_codes[code->index]; > > And here. > np >> +/* Request bus settings on camera side */ >> +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_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; > > This should come from DT instead. Could you add DT binding documentation > for the sensor, please? There's already some for ov9650; I wonder how > similar that one is. The platform doesn't support it yet, so I have no way to test any DT patches. >> + cfg->type = V4L2_MBUS_PARALLEL; >> + cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); >> + >> + return 0; >> +} >> + >> +static const struct v4l2_subdev_video_ops ov9640_video_ops = { >> + .s_stream = ov9640_s_stream, >> + .g_mbus_config = ov9640_g_mbus_config, >> +}; >> + >> +static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { >> + .enum_mbus_code = ov9640_enum_mbus_code, >> + .get_selection = ov9640_get_selection, >> + .set_fmt = ov9640_set_fmt, > > Please add an operating to get the format as well. OK, but it will be tested on a preliminary hacked pxa-camera :-). > >> +}; >> + >> +static const struct v4l2_subdev_ops ov9640_subdev_ops = { >> + .core = &ov9640_core_ops, >> + .video = &ov9640_video_ops, >> + .pad = &ov9640_pad_ops, >> +}; >> + >> +/* >> + * i2c_driver function >> + */ >> +static int ov9640_probe(struct i2c_client *client, >> + const struct i2c_device_id *did) >> +{ >> + struct ov9640_priv *priv; >> + struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); >> + int ret; >> + >> + if (!ssdd) { >> + dev_err(&client->dev, "Missing platform_data for driver\n"); >> + return -EINVAL; >> + } >> + >> + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); >> + if (!priv) >> + return -ENOMEM; >> + >> + v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops); >> + >> + v4l2_ctrl_handler_init(&priv->hdl, 2); >> + v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops, >> + V4L2_CID_VFLIP, 0, 1, 1, 0); >> + 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) > > v4l2_ctrl_handler_free() is missing here. The function would benefit from > goto-based error handling. > + rest -> np best regards, pc2005