media: atomisp: Add atomisp_register_sensor_no_gmin() helper
authorHans de Goede <hdegoede@redhat.com>
Sun, 15 Jan 2023 21:09:57 +0000 (22:09 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Wed, 8 Feb 2023 07:05:59 +0000 (08:05 +0100)
The DSDT of all Windows BYT / CHT devices which I have seen has proper
ACPI powermagement for the clk and regulators used by the sensors.

So there is no need for the whole custom atomisp_gmin custom code to
disable the ACPI pm and directly poke at the PMIC for this.

Add new atomisp_register_sensor_no_gmin() + atomisp_unregister_subdev()
helpers which allow registering a sensor with the atomisp code without
using any of the atomisp_gmin power-management code.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/staging/media/atomisp/include/linux/atomisp_platform.h
drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c

index 82973aa0e1eb14e0e04d79f2738a92d8085693ee..539b21d39d3be6d99cd127c9ede87fdeb19639b6 100644 (file)
@@ -211,6 +211,10 @@ struct camera_mipi_info {
 };
 
 const struct atomisp_platform_data *atomisp_get_platform_data(void);
+int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
+                                   enum atomisp_input_format format,
+                                   enum atomisp_bayer_order bayer_order);
+void atomisp_unregister_subdev(struct v4l2_subdev *subdev);
 
 /* API from old platform_camera.h, new CPUID implementation */
 #define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
index ea363f25196c6d61a1f257b6ed9c3ffd8e4523f8..34497b4b91d249ef94eb9b8a7090595656708b02 100644 (file)
@@ -1084,6 +1084,67 @@ static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag)
        return 0;
 }
 
+int atomisp_register_sensor_no_gmin(struct v4l2_subdev *subdev, u32 lanes,
+                                   enum atomisp_input_format format,
+                                   enum atomisp_bayer_order bayer_order)
+{
+       struct i2c_client *client = v4l2_get_subdevdata(subdev);
+       struct acpi_device *adev = ACPI_COMPANION(&client->dev);
+       int i, ret, clock_num, port = 0;
+
+       if (adev) {
+               /* Get ACPI _PR0 derived clock to determine the csi_port default */
+               if (acpi_device_power_manageable(adev)) {
+                       clock_num = atomisp_get_acpi_power(&client->dev);
+
+                       /* Compare clock to CsiPort 1 pmc-clock used in the CHT/BYT reference designs */
+                       if (IS_ISP2401)
+                               port = clock_num == 4 ? 1 : 0;
+                       else
+                               port = clock_num == 0 ? 1 : 0;
+               }
+
+               port = gmin_get_var_int(&client->dev, false, "CsiPort", port);
+               lanes = gmin_get_var_int(&client->dev, false, "CsiLanes", lanes);
+       }
+
+       for (i = 0; i < MAX_SUBDEVS; i++)
+               if (!pdata.subdevs[i].type)
+                       break;
+
+       if (i >= MAX_SUBDEVS) {
+               dev_err(&client->dev, "Error too many subdevs already registered\n");
+               return -ENOMEM;
+       }
+
+       ret = camera_sensor_csi_alloc(subdev, port, lanes, format, bayer_order);
+       if (ret)
+               return ret;
+
+       pdata.subdevs[i].type = RAW_CAMERA;
+       pdata.subdevs[i].port = port;
+       pdata.subdevs[i].subdev = subdev;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(atomisp_register_sensor_no_gmin);
+
+void atomisp_unregister_subdev(struct v4l2_subdev *subdev)
+{
+       int i;
+
+       for (i = 0; i < MAX_SUBDEVS; i++) {
+               if (pdata.subdevs[i].subdev != subdev)
+                       continue;
+
+               camera_sensor_csi_free(subdev);
+               pdata.subdevs[i].subdev = NULL;
+               pdata.subdevs[i].type = 0;
+               pdata.subdevs[i].port = 0;
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(atomisp_unregister_subdev);
+
 static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev,
        char *camera_module)
 {