MLK-18130: camera: add two ov5640 sensor support for QM
authorGuoniu.Zhou <guoniu.zhou@nxp.com>
Wed, 25 Apr 2018 09:28:32 +0000 (17:28 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
Add two ov5640 sensors support for QM since it has two
MIPI CSI controller.

Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
drivers/media/platform/imx8/ov5640_mipi_v3.c

index f111724..0dfdbec 100644 (file)
@@ -119,15 +119,10 @@ struct ov5640 {
        struct clk *sensor_clk;
        int csi;
 
-       void (*io_init)(void);
+       void (*io_init)(struct ov5640 *);
+       int pwn_gpio, rst_gpio;
 };
 
-/*!
- * Maintains the information on the current state of the sesor.
- */
-static struct ov5640 ov5640_data;
-static int pwn_gpio, rst_gpio;
-
 static struct reg_value ov5640_init_parm[] = {
        {0x3008, 0x42, 0, 0},
 
@@ -531,8 +526,8 @@ static int ov5640_probe(struct i2c_client *adapter,
                                const struct i2c_device_id *device_id);
 static int ov5640_remove(struct i2c_client *client);
 
-static s32 ov5640_read_reg(u16 reg, u8 *val);
-static s32 ov5640_write_reg(u16 reg, u8 val);
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val);
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val);
 
 static const struct i2c_device_id ov5640_id[] = {
        {"ov5640_mipi_v3", 0},
@@ -595,23 +590,23 @@ static const struct ov5640_datafmt
        return NULL;
 }
 
-static inline void ov5640_power_down(int enable)
+static inline void ov5640_power_down(struct ov5640 *sensor, int enable)
 {
-       gpio_set_value_cansleep(pwn_gpio, enable);
+       gpio_set_value_cansleep(sensor->pwn_gpio, enable);
 
        udelay(2000);
 }
 
-static inline void ov5640_reset(void)
+static inline void ov5640_reset(struct ov5640 *sensor)
 {
-       gpio_set_value_cansleep(pwn_gpio, 1);
-       gpio_set_value_cansleep(rst_gpio, 0);
+       gpio_set_value_cansleep(sensor->pwn_gpio, 1);
+       gpio_set_value_cansleep(sensor->rst_gpio, 0);
        udelay(5000);
 
-       gpio_set_value_cansleep(pwn_gpio, 0);
+       gpio_set_value_cansleep(sensor->pwn_gpio, 0);
        udelay(1000);
 
-       gpio_set_value_cansleep(rst_gpio, 1);
+       gpio_set_value_cansleep(sensor->rst_gpio, 1);
        msleep(20);
 }
 
@@ -671,40 +666,39 @@ static int ov5640_regulator_enable(struct device *dev)
        return ret;
 }
 
-static s32 ov5640_write_reg(u16 reg, u8 val)
+static s32 ov5640_write_reg(struct ov5640 *sensor, u16 reg, u8 val)
 {
+       struct device *dev = &sensor->i2c_client->dev;
        u8 au8Buf[3] = {0};
 
        au8Buf[0] = reg >> 8;
        au8Buf[1] = reg & 0xff;
        au8Buf[2] = val;
 
-       if (i2c_master_send(ov5640_data.i2c_client, au8Buf, 3) < 0) {
-               pr_err("%s:write reg error:reg=%x,val=%x\n",
-                       __func__, reg, val);
+       if (i2c_master_send(sensor->i2c_client, au8Buf, 3) < 0) {
+               dev_err(dev, "Write reg error: reg=%x, val=%x\n", reg, val);
                return -1;
        }
 
        return 0;
 }
 
-static s32 ov5640_read_reg(u16 reg, u8 *val)
+static s32 ov5640_read_reg(struct ov5640 *sensor, u16 reg, u8 *val)
 {
+       struct device *dev = &sensor->i2c_client->dev;
        u8 au8RegBuf[2] = {0};
        u8 u8RdVal = 0;
 
        au8RegBuf[0] = reg >> 8;
        au8RegBuf[1] = reg & 0xff;
 
-       if (i2c_master_send(ov5640_data.i2c_client, au8RegBuf, 2) != 2) {
-               pr_err("%s:write reg error:reg=%x\n",
-                               __func__, reg);
+       if (i2c_master_send(sensor->i2c_client, au8RegBuf, 2) != 2) {
+               dev_err(dev, "Read reg error: reg=%x\n", reg);
                return -1;
        }
 
-       if (i2c_master_recv(ov5640_data.i2c_client, &u8RdVal, 1) != 1) {
-               pr_err("%s:read reg error:reg=%x,val=%x\n",
-                               __func__, reg, u8RdVal);
+       if (i2c_master_recv(sensor->i2c_client, &u8RdVal, 1) != 1) {
+               dev_err(dev, "Read reg error: reg=%x, val=%x\n", reg, u8RdVal);
                return -1;
        }
 
@@ -713,26 +707,27 @@ static s32 ov5640_read_reg(u16 reg, u8 *val)
        return u8RdVal;
 }
 
-static int ov5640_set_clk_rate(void)
+static int ov5640_set_clk_rate(struct ov5640 *sensor)
 {
        u32 tgt_xclk;   /* target xclk */
        int ret;
 
        /* mclk */
-       tgt_xclk = ov5640_data.mclk;
+       tgt_xclk = sensor->mclk;
        tgt_xclk = min_t(u32, tgt_xclk, (u32)OV5640_XCLK_MAX);
        tgt_xclk = max_t(u32, tgt_xclk, (u32)OV5640_XCLK_MIN);
-       ov5640_data.mclk = tgt_xclk;
+       sensor->mclk = tgt_xclk;
 
        pr_debug("   Setting mclk to %d MHz\n", tgt_xclk / 1000000);
-       ret = clk_set_rate(ov5640_data.sensor_clk, ov5640_data.mclk);
+       ret = clk_set_rate(sensor->sensor_clk, sensor->mclk);
        if (ret < 0)
-               pr_debug("set rate filed, rate=%d\n", ov5640_data.mclk);
+               pr_debug("set rate filed, rate=%d\n", sensor->mclk);
        return ret;
 }
 
 /* download ov5640 settings to sensor through i2c */
-static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
+static int ov5640_download_firmware(struct ov5640 *sensor,
+                               struct reg_value *pModeSetting, s32 ArySize)
 {
        register u32 Delay_ms = 0;
        register u16 RegAddr = 0;
@@ -748,7 +743,7 @@ static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
                Mask = pModeSetting->u8Mask;
 
                if (Mask) {
-                       retval = ov5640_read_reg(RegAddr, &RegVal);
+                       retval = ov5640_read_reg(sensor, RegAddr, &RegVal);
                        if (retval < 0)
                                goto err;
 
@@ -757,7 +752,7 @@ static int ov5640_download_firmware(struct reg_value *pModeSetting, s32 ArySize)
                        Val |= RegVal;
                }
 
-               retval = ov5640_write_reg(RegAddr, Val);
+               retval = ov5640_write_reg(sensor, RegAddr, Val);
                if (retval < 0)
                        goto err;
 
@@ -768,19 +763,19 @@ err:
        return retval;
 }
 
-static void ov5640_soft_reset(void)
+static void ov5640_soft_reset(struct ov5640 *sensor)
 {
        /* sysclk from pad */
-       ov5640_write_reg(0x3103, 0x11);
+       ov5640_write_reg(sensor, 0x3103, 0x11);
 
        /* software reset */
-       ov5640_write_reg(0x3008, 0x82);
+       ov5640_write_reg(sensor, 0x3008, 0x82);
 
        /* delay at least 5ms */
        msleep(10);
 }
 
-static int ov5640_config_init(void)
+static int ov5640_config_init(struct ov5640 *sensor)
 {
        struct reg_value *pModeSetting = NULL;
        int ArySize = 0, retval = 0;
@@ -789,14 +784,15 @@ static int ov5640_config_init(void)
        pModeSetting = ov5640_init_parm;
        ArySize = ARRAY_SIZE(ov5640_init_parm);
 
-       retval = ov5640_download_firmware(pModeSetting, ArySize);
+       retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
        if (retval < 0)
                return retval;
 
        return 0;
 }
 
-static int ov5640_config_resolution(enum ov5640_mode mode)
+static int ov5640_config_resolution(struct ov5640 *sensor,
+                       enum ov5640_mode mode)
 {
        struct reg_value *pModeSetting = NULL;
        int ArySize = 0, retval = 0;
@@ -805,8 +801,8 @@ static int ov5640_config_resolution(enum ov5640_mode mode)
                return -EINVAL;
 
        if (mode == ov5640_mode_1080P_1920_1080) {
-               ov5640_write_reg(0x3709, 0x12);
-               ov5640_write_reg(0x3821, 0x06);
+               ov5640_write_reg(sensor, 0x3709, 0x12);
+               ov5640_write_reg(sensor, 0x3821, 0x06);
        }
 
        if (mode == ov5640_mode_480_272) {
@@ -818,15 +814,15 @@ static int ov5640_config_resolution(enum ov5640_mode mode)
        pModeSetting = ov5640_mode_info_data[mode].init_data_ptr;
        ArySize = ov5640_mode_info_data[mode].init_data_size;
 
-       retval = ov5640_download_firmware(pModeSetting, ArySize);
+       retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
        if (retval < 0)
                return retval;
 
        return 0;
 }
 
-static int ov5640_config_others(enum ov5640_frame_rate rate,
-                               enum ov5640_mode mode)
+static int ov5640_config_others(struct ov5640 *sensor,
+                       enum ov5640_frame_rate rate, enum ov5640_mode mode)
 {
        struct reg_value *pModeSetting = NULL;
        int ArySize = 0, retval = 0;
@@ -838,29 +834,29 @@ static int ov5640_config_others(enum ov5640_frame_rate rate,
                        ov5640_mode_VGA_640_480 : mode;
        pModeSetting = ov5640_mipi_pll_info_data[rate][mode].init_data_ptr;
        ArySize = ov5640_mipi_pll_info_data[rate][mode].init_data_size;
-       retval = ov5640_download_firmware(pModeSetting, ArySize);
+       retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
        if (retval < 0)
                return retval;
 
        /* Configure ov5640 initial parm */
        pModeSetting = ov5640_mipi_config;
        ArySize = ARRAY_SIZE(ov5640_mipi_config);
-       retval = ov5640_download_firmware(pModeSetting, ArySize);
+       retval = ov5640_download_firmware(sensor, pModeSetting, ArySize);
        if (retval < 0)
                return retval;
 
        return 0;
 }
 
-static void ov5640_start(void)
+static void ov5640_start(struct ov5640 *sensor)
 {
-       ov5640_write_reg(0x3008, 0x02);
-       ov5640_write_reg(0x3008, 0x02);
+       ov5640_write_reg(sensor, 0x3008, 0x02);
+       ov5640_write_reg(sensor, 0x3008, 0x02);
        udelay(1000);
 }
 
-static int ov5640_change_mode(enum ov5640_frame_rate rate,
-                       enum ov5640_mode mode)
+static int ov5640_change_mode(struct ov5640 *sensor,
+                       enum ov5640_frame_rate rate, enum ov5640_mode mode)
 {
        int retval;
 
@@ -869,13 +865,13 @@ static int ov5640_change_mode(enum ov5640_frame_rate rate,
                rate = ov5640_15_fps;
        }
 
-       retval = ov5640_config_resolution(mode);
+       retval = ov5640_config_resolution(sensor, mode);
        if (retval < 0) {
                pr_err("%s config resolution fail\n", __func__);
                return -EINVAL;
        }
 
-       retval = ov5640_config_others(rate, mode);
+       retval = ov5640_config_others(sensor, rate, mode);
        if (retval < 0) {
                pr_err("%s config others fail\n", __func__);
                return -EINVAL;
@@ -884,31 +880,32 @@ static int ov5640_change_mode(enum ov5640_frame_rate rate,
        return 0;
 }
 
-static int init_device(void)
+static int init_device(struct ov5640 *sensor)
 {
        int retval;
 
-       ov5640_soft_reset();
-       retval = ov5640_config_init();
+       ov5640_soft_reset(sensor);
+       retval = ov5640_config_init(sensor);
        if (retval < 0)
                return retval;
 
-       retval = ov5640_config_resolution(ov5640_mode_VGA_640_480);
+       retval = ov5640_config_resolution(sensor, ov5640_mode_VGA_640_480);
        if (retval < 0)
                return retval;
 
-       retval = ov5640_config_others(ov5640_30_fps, ov5640_mode_VGA_640_480);
+       retval = ov5640_config_others(sensor, ov5640_30_fps,
+                               ov5640_mode_VGA_640_480);
        if (retval < 0)
                return retval;
 
-       ov5640_start();
+       ov5640_start(sensor);
 
        return 0;
 }
 
-static void ov5640_stop(void)
+static void ov5640_stop(struct ov5640 *sensor)
 {
-       ov5640_write_reg(0x3008, 0x42);
+       ov5640_write_reg(sensor, 0x3008, 0x42);
        udelay(1000);
 }
 
@@ -926,9 +923,9 @@ static int ov5640_s_power(struct v4l2_subdev *sd, int on)
        struct ov5640 *sensor = to_ov5640(client);
 
        if (on)
-               clk_prepare_enable(ov5640_data.sensor_clk);
+               clk_prepare_enable(sensor->sensor_clk);
        else
-               clk_disable_unprepare(ov5640_data.sensor_clk);
+               clk_disable_unprepare(sensor->sensor_clk);
 
        sensor->on = on;
        return 0;
@@ -1039,7 +1036,7 @@ static int ov5640_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
                        goto error;
                }
 
-               ret = ov5640_change_mode(frame_rate, mode);
+               ret = ov5640_change_mode(sensor, frame_rate, mode);
                if (ret < 0)
                        goto error;
 
@@ -1078,9 +1075,9 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
        struct ov5640 *sensor = to_ov5640(client);
 
        if (enable)
-               ov5640_start();
+               ov5640_start(sensor);
        else
-               ov5640_stop();
+               ov5640_stop(sensor);
 
        sensor->on = enable;
        return 0;
@@ -1099,11 +1096,11 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
                return -EINVAL;
 
        if (!fmt) {
-               mf->code        = ov5640_colour_fmts[1].code;
-               mf->colorspace  = ov5640_colour_fmts[1].colorspace;
+               mf->code = ov5640_colour_fmts[1].code;
+               mf->colorspace = ov5640_colour_fmts[1].colorspace;
        }
 
-       mf->field       = V4L2_FIELD_NONE;
+       mf->field = V4L2_FIELD_NONE;
 
        if (format->which == V4L2_SUBDEV_FORMAT_TRY)
                return 0;
@@ -1268,6 +1265,11 @@ static int ov5640_probe(struct i2c_client *client,
        struct v4l2_subdev *sd;
        int retval;
        u8 chip_id_high, chip_id_low;
+       struct ov5640 *sensor;
+
+       sensor = kmalloc(sizeof(*sensor), GFP_KERNEL);
+       /* Set initial values for the sensor struct. */
+       memset(sensor, 0, sizeof(*sensor));
 
        /* ov5640 pinctrl */
        pinctrl = devm_pinctrl_get_select_default(dev);
@@ -1277,115 +1279,118 @@ static int ov5640_probe(struct i2c_client *client,
        }
 
        /* request power down pin */
-       pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
-       if (!gpio_is_valid(pwn_gpio)) {
-               dev_err(dev, "no sensor pwdn pin available\n");
-               return -ENODEV;
+       sensor->pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
+       if (!gpio_is_valid(sensor->pwn_gpio))
+               dev_warn(dev, "No sensor pwdn pin available");
+       else {
+               retval = devm_gpio_request_one(dev, sensor->pwn_gpio,
+                               GPIOF_OUT_INIT_HIGH, "ov5640_mipi_pwdn");
+               if (retval < 0) {
+                       dev_warn(dev, "Failed to set power pin\n");
+                       dev_warn(dev, "retval=%d\n", retval);
+                       return retval;
+               }
        }
-       retval = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
-                                       "ov5640_pwdn");
-       if (retval < 0)
-               return retval;
 
        /* request reset pin */
-       rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
-       if (!gpio_is_valid(rst_gpio)) {
-               dev_err(dev, "no sensor reset pin available\n");
-               devm_gpio_free(dev, rst_gpio);
-               return -EINVAL;
-       }
-       retval = devm_gpio_request_one(dev, rst_gpio, GPIOF_OUT_INIT_LOW,
-                                       "ov5640_reset");
-       if (retval < 0) {
-               devm_gpio_free(dev, pwn_gpio);
-               return retval;
+       sensor->rst_gpio = of_get_named_gpio(dev->of_node, "rst-gpios", 0);
+       if (!gpio_is_valid(sensor->rst_gpio))
+               dev_warn(dev, "No sensor reset pin available");
+       else {
+               retval = devm_gpio_request_one(dev, sensor->rst_gpio,
+                               GPIOF_OUT_INIT_HIGH, "ov5640_mipi_reset");
+               if (retval < 0) {
+                       dev_warn(dev, "Failed to set reset pin\n");
+                       return retval;
+               }
        }
 
        /* Set initial values for the sensor struct. */
-       memset(&ov5640_data, 0, sizeof(ov5640_data));
-       ov5640_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
-       if (IS_ERR(ov5640_data.sensor_clk)) {
-               dev_err(dev, "get mclk failed\n");
-               devm_gpio_free(dev, pwn_gpio);
-               devm_gpio_free(dev, rst_gpio);
-               return PTR_ERR(ov5640_data.sensor_clk);
+       sensor->sensor_clk = devm_clk_get(dev, "csi_mclk");
+       if (IS_ERR(sensor->sensor_clk)) {
+               /* assuming clock enabled by default */
+               sensor->sensor_clk = NULL;
+               dev_err(dev, "clock-frequency missing or invalid\n");
+               return PTR_ERR(sensor->sensor_clk);
        }
 
        retval = of_property_read_u32(dev->of_node, "mclk",
-                                       &ov5640_data.mclk);
+                                       &(sensor->mclk));
        if (retval) {
-               dev_err(dev, "mclk frequency is invalid\n");
+               dev_err(dev, "mclk missing or invalid\n");
                return retval;
        }
 
        retval = of_property_read_u32(dev->of_node, "mclk_source",
-                                       (u32 *) &(ov5640_data.mclk_source));
+                                       (u32 *) &(sensor->mclk_source));
        if (retval) {
-               dev_err(dev, "mclk_source invalid\n");
+               dev_err(dev, "mclk_source missing or invalid\n");
                return retval;
        }
 
        retval = of_property_read_u32(dev->of_node, "csi_id",
-                               &(ov5640_data.csi));
+                                       &(sensor->csi));
        if (retval) {
-               dev_err(dev, "csi_id invalid\n");
+               dev_err(dev, "csi id missing or invalid\n");
                return retval;
        }
 
        /* Set mclk rate before clk on */
-       ov5640_set_clk_rate();
+       ov5640_set_clk_rate(sensor);
 
-       retval = clk_prepare_enable(ov5640_data.sensor_clk);
+       retval = clk_prepare_enable(sensor->sensor_clk);
        if (retval < 0) {
                dev_err(dev, "%s: enable sensor clk fail\n", __func__);
                return -EINVAL;
        }
 
-       ov5640_data.io_init = ov5640_reset;
-       ov5640_data.i2c_client = client;
+       sensor->io_init = ov5640_reset;
+       sensor->i2c_client = client;
 
-       ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
-       ov5640_data.pix.width = ov5640_mode_info_data[0].width;
-       ov5640_data.pix.height =  ov5640_mode_info_data[0].height;
-       ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+       sensor->pix.pixelformat = V4L2_PIX_FMT_UYVY;
+       sensor->pix.width = ov5640_mode_info_data[0].width;
+       sensor->pix.height =  ov5640_mode_info_data[0].height;
+       sensor->streamcap.capability = V4L2_MODE_HIGHQUALITY |
                                           V4L2_CAP_TIMEPERFRAME;
-       ov5640_data.streamcap.capturemode = 0;
-       ov5640_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
-       ov5640_data.streamcap.timeperframe.numerator = 1;
+       sensor->streamcap.capturemode = 0;
+       sensor->streamcap.timeperframe.denominator = DEFAULT_FPS;
+       sensor->streamcap.timeperframe.numerator = 1;
 
        ov5640_regulator_enable(&client->dev);
 
-       ov5640_reset();
+       ov5640_reset(sensor);
 
-       retval = ov5640_read_reg(OV5640_CHIP_ID_HIGH_BYTE, &chip_id_high);
+       retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_HIGH_BYTE,
+                               &chip_id_high);
        if (retval < 0 || chip_id_high != 0x56) {
-               clk_disable_unprepare(ov5640_data.sensor_clk);
+               clk_disable_unprepare(sensor->sensor_clk);
                pr_warn("camera ov5640 is not found\n");
                return -ENODEV;
        }
-       retval = ov5640_read_reg(OV5640_CHIP_ID_LOW_BYTE, &chip_id_low);
+       retval = ov5640_read_reg(sensor, OV5640_CHIP_ID_LOW_BYTE,
+                               &chip_id_low);
        if (retval < 0 || chip_id_low != 0x40) {
-               clk_disable_unprepare(ov5640_data.sensor_clk);
+               clk_disable_unprepare(sensor->sensor_clk);
                pr_warn("camera ov5640 is not found\n");
                return -ENODEV;
        }
 
-       retval = init_device();
+       retval = init_device(sensor);
        if (retval < 0) {
-               clk_disable_unprepare(ov5640_data.sensor_clk);
+               clk_disable_unprepare(sensor->sensor_clk);
                pr_warn("camera ov5640 init fail\n");
                return -ENODEV;
        }
 
-       sd = &ov5640_data.subdev;
+       sd = &sensor->subdev;
        v4l2_i2c_subdev_init(sd, client, &ov5640_subdev_ops);
 
        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
        sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
-       ov5640_data.pads[OV5640_SENS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+       sensor->pads[OV5640_SENS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
        retval = media_entity_pads_init(&sd->entity, OV5640_SENS_PADS_NUM,
-                                                       ov5640_data.pads);
+                                                       sensor->pads);
        sd->entity.ops = &ov5640_sd_media_ops;
        if (retval < 0)
                return retval;
@@ -1393,11 +1398,11 @@ static int ov5640_probe(struct i2c_client *client,
        retval = v4l2_async_register_subdev(sd);
        if (retval < 0) {
                dev_err(&client->dev,
-                                       "%s--Async register failed, ret=%d\n", __func__, retval);
+                               "%s--Async register failed, ret=%d\n", __func__, retval);
                media_entity_cleanup(&sd->entity);
        }
 
-       clk_disable_unprepare(ov5640_data.sensor_clk);
+       clk_disable_unprepare(sensor->sensor_clk);
 
        pr_info("%s camera mipi ov5640, is found\n", __func__);
        return retval;
@@ -1412,12 +1417,13 @@ static int ov5640_probe(struct i2c_client *client,
 static int ov5640_remove(struct i2c_client *client)
 {
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
+       struct ov5640 *sensor = to_ov5640(client);
 
        v4l2_async_unregister_subdev(sd);
 
-       clk_unprepare(ov5640_data.sensor_clk);
+       clk_unprepare(sensor->sensor_clk);
 
-       ov5640_power_down(1);
+       ov5640_power_down(sensor, 1);
 
        if (analog_regulator)
                regulator_disable(analog_regulator);