Slightly different version of MT9M114 camera module is used in a several
devices like ASUS Nexus 7 (2012) or ASUS Transformer Prime TF201 and is
called Aptina MI1040. The only difference found so far is lacking ability
to poll STATE register during power on sequence, which causes driver to
fail with time out error. Add state_standby_polling flag to diverge models
and address quirk found in MI1040.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/media/i2c/mt9m114.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index 16b0ace15813..e395e2d14e97 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -368,6 +368,10 @@
* Data Structures
*/
+struct mt9m114_model_info {
+ bool state_standby_polling;
+};
+
enum mt9m114_format_flag {
MT9M114_FMT_FLAG_PARALLEL = BIT(0),
MT9M114_FMT_FLAG_CSI2 = BIT(1),
@@ -417,6 +421,8 @@ struct mt9m114 {
struct v4l2_ctrl *tpg[4];
} ifp;
+
+ const struct mt9m114_model_info *info;
};
/* -----------------------------------------------------------------------------
@@ -2284,9 +2290,11 @@ static int mt9m114_power_on(struct mt9m114 *sensor)
* reaches the standby mode (either initiated manually above in
* parallel mode, or automatically after reset in MIPI mode).
*/
- ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY);
- if (ret < 0)
- goto error_clock;
+ if (sensor->info->state_standby_polling) {
+ ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY);
+ if (ret < 0)
+ goto error_clock;
+ }
return 0;
@@ -2532,6 +2540,10 @@ static int mt9m114_probe(struct i2c_client *client)
if (ret < 0)
return ret;
+ sensor->info = device_get_match_data(dev);
+ if (!sensor->info)
+ return -ENODEV;
+
/* Acquire clocks, GPIOs and regulators. */
sensor->clk = devm_v4l2_sensor_clk_get(dev, NULL);
if (IS_ERR(sensor->clk)) {
@@ -2646,15 +2658,24 @@ static void mt9m114_remove(struct i2c_client *client)
pm_runtime_set_suspended(dev);
}
+static const struct mt9m114_model_info mt9m114_models_default = {
+ .state_standby_polling = true,
+};
+
+static const struct mt9m114_model_info mt9m114_models_aptina = {
+ .state_standby_polling = false,
+};
+
static const struct of_device_id mt9m114_of_ids[] = {
- { .compatible = "onnn,mt9m114" },
- { /* sentinel */ },
+ { .compatible = "onnn,mt9m114", .data = &mt9m114_models_default },
+ { .compatible = "aptina,mi1040", .data = &mt9m114_models_aptina },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mt9m114_of_ids);
static const struct acpi_device_id mt9m114_acpi_ids[] = {
- { "INT33F0" },
- { /* sentinel */ },
+ { "INT33F0", (kernel_ulong_t)&mt9m114_models_default },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(acpi, mt9m114_acpi_ids);
--
2.51.0
Hi,
On 5-Mar-26 11:21, Svyatoslav Ryhel wrote:
> Slightly different version of MT9M114 camera module is used in a several
> devices like ASUS Nexus 7 (2012) or ASUS Transformer Prime TF201 and is
> called Aptina MI1040. The only difference found so far is lacking ability
> to poll STATE register during power on sequence, which causes driver to
> fail with time out error. Add state_standby_polling flag to diverge models
> and address quirk found in MI1040.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Thanks, patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Regards,
Hans
> ---
> drivers/media/i2c/mt9m114.c | 35 ++++++++++++++++++++++++++++-------
> 1 file changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
> index 16b0ace15813..e395e2d14e97 100644
> --- a/drivers/media/i2c/mt9m114.c
> +++ b/drivers/media/i2c/mt9m114.c
> @@ -368,6 +368,10 @@
> * Data Structures
> */
>
> +struct mt9m114_model_info {
> + bool state_standby_polling;
> +};
> +
> enum mt9m114_format_flag {
> MT9M114_FMT_FLAG_PARALLEL = BIT(0),
> MT9M114_FMT_FLAG_CSI2 = BIT(1),
> @@ -417,6 +421,8 @@ struct mt9m114 {
>
> struct v4l2_ctrl *tpg[4];
> } ifp;
> +
> + const struct mt9m114_model_info *info;
> };
>
> /* -----------------------------------------------------------------------------
> @@ -2284,9 +2290,11 @@ static int mt9m114_power_on(struct mt9m114 *sensor)
> * reaches the standby mode (either initiated manually above in
> * parallel mode, or automatically after reset in MIPI mode).
> */
> - ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY);
> - if (ret < 0)
> - goto error_clock;
> + if (sensor->info->state_standby_polling) {
> + ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY);
> + if (ret < 0)
> + goto error_clock;
> + }
>
> return 0;
>
> @@ -2532,6 +2540,10 @@ static int mt9m114_probe(struct i2c_client *client)
> if (ret < 0)
> return ret;
>
> + sensor->info = device_get_match_data(dev);
> + if (!sensor->info)
> + return -ENODEV;
> +
> /* Acquire clocks, GPIOs and regulators. */
> sensor->clk = devm_v4l2_sensor_clk_get(dev, NULL);
> if (IS_ERR(sensor->clk)) {
> @@ -2646,15 +2658,24 @@ static void mt9m114_remove(struct i2c_client *client)
> pm_runtime_set_suspended(dev);
> }
>
> +static const struct mt9m114_model_info mt9m114_models_default = {
> + .state_standby_polling = true,
> +};
> +
> +static const struct mt9m114_model_info mt9m114_models_aptina = {
> + .state_standby_polling = false,
> +};
> +
> static const struct of_device_id mt9m114_of_ids[] = {
> - { .compatible = "onnn,mt9m114" },
> - { /* sentinel */ },
> + { .compatible = "onnn,mt9m114", .data = &mt9m114_models_default },
> + { .compatible = "aptina,mi1040", .data = &mt9m114_models_aptina },
> + { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, mt9m114_of_ids);
>
> static const struct acpi_device_id mt9m114_acpi_ids[] = {
> - { "INT33F0" },
> - { /* sentinel */ },
> + { "INT33F0", (kernel_ulong_t)&mt9m114_models_default },
> + { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(acpi, mt9m114_acpi_ids);
>
© 2016 - 2026 Red Hat, Inc.