summaryrefslogtreecommitdiff
path: root/drivers/media/platform/imx8
diff options
context:
space:
mode:
authorSandor Yu <Sandor.yu@nxp.com>2017-12-13 16:07:47 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit437063af36a5eb580f63ae97c7836e2bc188761e (patch)
tree8b469d6747b122baf7efdf04f0cc984e532887eb /drivers/media/platform/imx8
parent649e54ffe9557f625317afa86670556ae96b4bef (diff)
MLK-17208-1: mipi sensor: Reorder mipi CSI-2 sensor output
Reorder sensor to support different cameras combination. Driver can support 1 ~ 4 cameras when device bootup. And cameras should be connected according camera daughter marked. For example: one camera case: connected camera to IN0 on board. two cameras case: Connected cameras to IN0 and IN1 on board. ... Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
Diffstat (limited to 'drivers/media/platform/imx8')
-rw-r--r--drivers/media/platform/imx8/max9286.c114
1 files changed, 100 insertions, 14 deletions
diff --git a/drivers/media/platform/imx8/max9286.c b/drivers/media/platform/imx8/max9286.c
index 438cd9cb781c..7696f85f8675 100644
--- a/drivers/media/platform/imx8/max9286.c
+++ b/drivers/media/platform/imx8/max9286.c
@@ -2153,7 +2153,7 @@ static int ov10635_check_device(struct sensor_data *max9286_data, int index)
return 0;
}
-static int ov10635_initialize(struct sensor_data *max9286_data, int index, int sensor_num)
+static int ov10635_initialize(struct sensor_data *max9286_data, int index)
{
int i, array_size;
int retval;
@@ -2376,6 +2376,70 @@ static int max9286_hardware_preinit(struct sensor_data *max9286_data)
return 0;
}
+
+static void max9286_camera_reorder(struct sensor_data *max9286_data)
+{
+ u8 reg;
+
+ reg = 0xE4;
+ if (max9286_data->sensor_num == 1) {
+ switch (max9286_data->sensor_is_there) {
+ case 0x8:
+ reg = 0x27;
+ break;
+ case 0x4:
+ reg = 0xC6;
+ break;
+ case 0x2:
+ reg = 0xE1;
+ break;
+ case 0x1:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ } else if (max9286_data->sensor_num == 2) {
+ switch (max9286_data->sensor_is_there) {
+ case 0xC:
+ reg = 0x4E;
+ break;
+ case 0xA:
+ reg = 0x72;
+ break;
+ case 0x9:
+ reg = 0x78;
+ break;
+ case 0x6:
+ reg = 0xD2;
+ break;
+ case 0x5:
+ reg = 0xD8;
+ break;
+ case 0x3:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ } else if (max9286_data->sensor_num == 3) {
+ switch (max9286_data->sensor_is_there) {
+ case 0xE:
+ reg = 0x93;
+ break;
+ case 0xD:
+ reg = 0x9C;
+ break;
+ case 0xB:
+ reg = 0xB4;
+ break;
+ case 0x7:
+ default:
+ reg = 0xE4;
+ break;
+ }
+ }
+ max9286_write_reg(max9286_data, 0x0B, reg);
+}
+
static int max9286_hardware_init(struct sensor_data *max9286_data)
{
int retval = 0;
@@ -2387,6 +2451,9 @@ static int max9286_hardware_init(struct sensor_data *max9286_data)
/* Disable PRBS test */
max9286_write_reg(max9286_data, 0x0E, 0x50);
+ /* reorder camera */
+ max9286_camera_reorder(max9286_data);
+
/* Enable all links */
reg = 0xE0 | max9286_data->sensor_is_there;
max9286_write_reg(max9286_data, 0x00, reg);
@@ -2432,21 +2499,33 @@ static int max9286_hardware_init(struct sensor_data *max9286_data)
/* Initialize Camera Sensor */
/* STEP 49 */
#ifdef CONFIG_SENSOR_OV10635
- if (max9286_data->sensor_is_there & (0x1 << 0) &&
- ov10635_check_device(max9286_data, 1) == 0)
- ov10635_initialize(max9286_data, 0, max9286_data->sensor_num);
+ if (max9286_data->sensor_is_there & (0x1 << 0)) {
+ retval = ov10635_check_device(max9286_data, 1);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 0);
+ }
- if (max9286_data->sensor_is_there & (0x1 << 1) &&
- ov10635_check_device(max9286_data, 2) == 0)
- ov10635_initialize(max9286_data, 1, max9286_data->sensor_num);
+ if (max9286_data->sensor_is_there & (0x1 << 1)) {
+ retval = ov10635_check_device(max9286_data, 2);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 1);
+ }
- if (max9286_data->sensor_is_there & (0x1 << 2) &&
- ov10635_check_device(max9286_data, 3) == 0)
- ov10635_initialize(max9286_data, 2, max9286_data->sensor_num);
+ if (max9286_data->sensor_is_there & (0x1 << 2)) {
+ ov10635_check_device(max9286_data, 3);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 2);
+ }
- if (max9286_data->sensor_is_there & (0x1 << 3) &&
- ov10635_check_device(max9286_data, 4) == 0)
- ov10635_initialize(max9286_data, 3, max9286_data->sensor_num);
+ if (max9286_data->sensor_is_there & (0x1 << 3)) {
+ retval = ov10635_check_device(max9286_data, 4);
+ if (retval < 0)
+ return retval;
+ ov10635_initialize(max9286_data, 3);
+ }
#endif
/* Enable Local Auto I2C ACK */
@@ -2857,7 +2936,14 @@ static int max9286_probe(struct i2c_client *client,
media_entity_cleanup(&sd->entity);
}
- max9286_hardware_init(max9286_data);
+ retval = max9286_hardware_init(max9286_data);
+ if (retval < 0) {
+ dev_err(&client->dev, "camera init failed\n");
+ clk_disable_unprepare(max9286_data->sensor_clk);
+ media_entity_cleanup(&sd->entity);
+ v4l2_async_unregister_subdev(sd);
+ return retval;
+ }
max9286_data->running = 0;