Linux Mipi Csi2错误:无法获取时钟csi\U mclk

Linux Mipi Csi2错误:无法获取时钟csi\U mclk,linux,camera,linux-device-driver,embedded-linux,yocto,Linux,Camera,Linux Device Driver,Embedded Linux,Yocto,我一直在写mipi csi-2 imx290相机驱动程序。我遇到了csi_时钟错误 这是我的imx290_探头功能 static int imx290_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; int retval; int value; /* request reset pin */ x

我一直在写mipi csi-2 imx290相机驱动程序。我遇到了csi_时钟错误

这是我的imx290_探头功能

static int imx290_probe(struct i2c_client *client,
  const struct i2c_device_id *id)
{

  struct device *dev = &client->dev;
  int retval;
  int value;




  /* request reset pin */
  xclr = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
  if (!gpio_is_valid(xclr)) {
    dev_warn(dev, "no sensor reset pin available");
    return -EINVAL;
  }

  retval = devm_gpio_request_one(dev, xclr, GPIOF_OUT_INIT_LOW,"imx290_mipi_reset");
  if (retval < 0)
    return retval;


  /* Set initial values for the sensor struct. */
  memset(&imx290_data, 0, sizeof(imx290_data));
  imx290_data.sensor_clk = devm_clk_get(dev, "csi_mclk");

  if (IS_ERR(imx290_data.sensor_clk)) {

    /* assuming clock enabled by default */
    imx290_data.sensor_clk = NULL;
    dev_err(dev, "clock-frequency missing or invalid\n");
    return PTR_ERR(imx290_data.sensor_clk);
  }


  retval = of_property_read_u32(dev->of_node, "mclk",&(imx290_data.mclk));

  if (retval) {
    dev_err(dev, "mclk missing or invalid\n");
    return retval;
  }

  retval = of_property_read_u32(dev->of_node, "mclk_source",
          (u32 *) &(imx290_data.mclk_source));
  if (retval) {
    dev_err(dev, "mclk_source missing or invalid\n");
    return retval;
  }

  retval = of_property_read_u32(dev->of_node, "csi_id",
          &(imx290_data.csi));
  if (retval) {
    dev_err(dev, "csi id missing or invalid\n");
    return retval;
  }
  pr_info("Line 10 is Ok\n ");
  clk_prepare_enable(imx290_data.sensor_clk);

  imx290_data.io_init = imx290_reset;
  imx290_data.i2c_client = client;
  imx290_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
  imx290_data.pix.width = 1920;
  imx290_data.pix.height = 1080;
  imx290_data.streamcap.capability = V4L2_MODE_HIGHQUALITY | V4L2_CAP_TIMEPERFRAME;
  imx290_data.streamcap.capturemode = 0;
  imx290_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
  imx290_data.streamcap.timeperframe.numerator = 1;

  imx290_power_on(dev);

  imx290_reset();

  retval = imx290_write_reg(IMX290_REG_STANDBY, 0x1,NULL);

  imx290_int_device.priv = &imx290_data;
  retval = v4l2_int_device_register(&imx290_int_device);

  clk_disable_unprepare(imx290_data.sensor_clk);

  pr_info("camera imx290_mipi is found\n");
  return retval;
}
静态int imx290_探测器(结构i2c_客户端*client,
常量结构i2c(设备id*id)
{
结构设备*dev=&client->dev;
内部检索;
int值;
/*请求复位引脚*/
xclr=of_get_name_gpio(dev->of_节点,“rst gpios”,0);
如果(!gpio_是有效的(xclr)){
dev_警告(dev,“无传感器复位引脚可用”);
返回-艾因瓦尔;
}
retval=devm_gpio_request_one(dev、xclr、GPIOF_OUT_INIT_LOW,“imx290_mipi_reset”);
如果(返回值<0)
返回返回;
/*设置传感器结构的初始值*/
memset(&imx290_数据,0,sizeof(imx290_数据));
imx290_data.sensor_clk=dev_clk_get(dev,“csi_mclk”);
如果(是错误(imx290数据传感器时钟)){
/*假设时钟默认启用*/
imx290_data.sensor_clk=NULL;
dev_err(dev,“时钟频率丢失或无效”);
返回PTR_ERR(imx290_data.sensor_clk);
}
retval=of_property_read_u32(dev->of_node,“mclk”&(imx290_data.mclk));
如果(返回){
dev_err(dev,“mclk丢失或无效”);
返回返回;
}
retval=of_property_read_32(dev->of_节点,“mclk_源”,
(u32*)和(imx290_data.mclk_source));
如果(返回){
dev_err(dev,“mclk_源丢失或无效”);
返回返回;
}
retval=of_property_read_32(dev->of_节点,“csi_id”,
&(imx290_data.csi));
如果(返回){
dev_err(dev,“csi id丢失或无效”);
返回返回;
}
pr_信息(“第10行正常”);
时钟准备启用(imx290数据传感器时钟);
imx290_data.io_init=imx290_reset;
imx290_data.i2c_client=客户端;
imx290_data.pix.pixelformat=V4L2_pix_FMT_UYVY;
imx290_data.pix.width=1920;
imx290_data.pix.height=1080;
imx290_data.streamcap.capability=V4L2_MODE_high quality|V4L2_CAP_TIMEPERFRAME;
imx290_data.streamcap.capturemode=0;
imx290_data.streamcap.timeperframe.deminator=默认值\u FPS;
imx290_data.streamcap.timeperframe.numerator=1;
imx290电源开启(开发);
imx290_重置();
retval=imx290_write_reg(imx290_reg_备用,0x1,NULL);
imx290_int_device.priv=&imx290_data;
retval=v4l2输入设备寄存器(&imx290输入设备);
clk_disable_unprepare(imx290_data.sensor_clk);
pr_信息(“找到摄像头imx290_mipi\n”);
返回返回;
}
我还提供了设备树配置

imx290_mipi: imx290_mipi@1a {
    compatible = "sony,imx290lqr,imx290,imx290_camera";
    reg = <0x1a>;
    clocks = <&clks 200>;
    clock-names = "csi_mclk";   
    OVDD = <&reg_1p8v>;
    AVDD = <&reg_2p9v>;
    DVDD = <&reg_1p2v>;
    pwn-gpios = <&gpio1 6 1>;
    rst-gpios = <&gpio4 14 0>; /// xclr 
    ipu_id = <0>;
    csi_id = <0>;
    mclk = <37125000>;
    mclk_source = <0>;
    lanes = <4>;
}
imx290\u mipi:imx290_mipi@1a {
compatible=“索尼,imx290lqr,imx290,imx290_摄像头”;
reg=;
时钟=;
时钟名称=“csi_mclk”;
OVDD=;
AVDD=;
DVDD=;
pwn gpios=;
rst gpios=;///xclr
ipu_id=;
csi_id=;
mclk=;
mclk_源=;
车道=;
}
这样做可能会有什么问题,因为此探头的功能与ov5640摄像头探头的功能类似,并且在探测时不会出现任何错误。 我的头脑很混乱,我需要第二种意见和建议

谢谢

致意


Mustafa

您能检查驱动程序/媒体/i2c/soc\u摄像头/imx074.c吗?这似乎是香草内核中最接近您的示例。我非常确定SoC摄像头框架是传感器的理想位置。@0andriy您是否建议我将驱动程序包括在此目录中,然后编译它,或者根据此imx074.c驱动程序函数进行更改。?谢谢,我建议以imx074.c为例,启动驱动程序作为SoC摄像头框架的一部分。