* [PATCH 1/3] media: i2c: ak7375: Prepare for supporting another chip
@ 2023-11-01 10:22 Vincent Knecht
2023-11-01 10:22 ` [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support Vincent Knecht
2023-11-01 10:22 ` [PATCH 3/3] media: i2c: ak7375: Add support for ak7345 Vincent Knecht
0 siblings, 2 replies; 6+ messages in thread
From: Vincent Knecht @ 2023-11-01 10:22 UTC (permalink / raw)
To: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
Cc: Vincent Knecht
In view of adding support for at least one other chip,
change the driver to move chip-specific properties and
values in a common structure.
No functional changes.
Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org>
---
drivers/media/i2c/ak7375.c | 110 ++++++++++++++++++++++---------------
1 file changed, 66 insertions(+), 44 deletions(-)
diff --git a/drivers/media/i2c/ak7375.c b/drivers/media/i2c/ak7375.c
index 463b51d46320..3a14eff41531 100644
--- a/drivers/media/i2c/ak7375.c
+++ b/drivers/media/i2c/ak7375.c
@@ -10,30 +10,45 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#define AK7375_MAX_FOCUS_POS 4095
-/*
- * This sets the minimum granularity for the focus positions.
- * A value of 1 gives maximum accuracy for a desired focus position
- */
-#define AK7375_FOCUS_STEPS 1
-/*
- * This acts as the minimum granularity of lens movement.
- * Keep this value power of 2, so the control steps can be
- * uniformly adjusted for gradual lens movement, with desired
- * number of control steps.
- */
-#define AK7375_CTRL_STEPS 64
-#define AK7375_CTRL_DELAY_US 1000
-/*
- * The vcm may take up 10 ms (tDELAY) to power on and start taking
- * I2C messages. Based on AK7371 datasheet.
- */
-#define AK7375_POWER_DELAY_US 10000
+struct ak73xx_chipdef {
+ u8 reg_position;
+ u8 reg_cont;
+ u8 shift_pos;
+ u8 mode_active;
+ u8 mode_standby;
+ u16 focus_pos_max;
+ /*
+ * This sets the minimum granularity for the focus positions.
+ * A value of 1 gives maximum accuracy for a desired focus position
+ */
+ u16 focus_steps;
+ /*
+ * This acts as the minimum granularity of lens movement.
+ * Keep this value power of 2, so the control steps can be
+ * uniformly adjusted for gradual lens movement, with desired
+ * number of control steps.
+ */
+ u16 ctrl_steps;
+ u16 ctrl_delay_us;
+ /*
+ * The vcm may take time (tDELAY) to power on and start taking
+ * I2C messages.
+ */
+ u16 power_delay_us;
+};
-#define AK7375_REG_POSITION 0x0
-#define AK7375_REG_CONT 0x2
-#define AK7375_MODE_ACTIVE 0x0
-#define AK7375_MODE_STANDBY 0x40
+static const struct ak73xx_chipdef ak7375_cdef = {
+ .reg_position = 0x0,
+ .reg_cont = 0x2,
+ .shift_pos = 4, /* 12 bits position values, need to << 4 */
+ .mode_active = 0x0,
+ .mode_standby = 0x40,
+ .focus_pos_max = 4095,
+ .focus_steps = 1,
+ .ctrl_steps = 64,
+ .ctrl_delay_us = 1000,
+ .power_delay_us = 10000,
+};
static const char * const ak7375_supply_names[] = {
"vdd",
@@ -42,6 +57,7 @@ static const char * const ak7375_supply_names[] = {
/* ak7375 device structure */
struct ak7375_device {
+ const struct ak73xx_chipdef *cdef;
struct v4l2_ctrl_handler ctrls_vcm;
struct v4l2_subdev sd;
struct v4l2_ctrl *focus;
@@ -86,10 +102,11 @@ static int ak7375_i2c_write(struct ak7375_device *ak7375,
static int ak7375_set_ctrl(struct v4l2_ctrl *ctrl)
{
struct ak7375_device *dev_vcm = to_ak7375_vcm(ctrl);
+ const struct ak73xx_chipdef *cdef = dev_vcm->cdef;
if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE)
- return ak7375_i2c_write(dev_vcm, AK7375_REG_POSITION,
- ctrl->val << 4, 2);
+ return ak7375_i2c_write(dev_vcm, cdef->reg_position,
+ ctrl->val << cdef->shift_pos, 2);
return -EINVAL;
}
@@ -128,11 +145,12 @@ static int ak7375_init_controls(struct ak7375_device *dev_vcm)
{
struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
const struct v4l2_ctrl_ops *ops = &ak7375_vcm_ctrl_ops;
+ const struct ak73xx_chipdef *cdef = dev_vcm->cdef;
v4l2_ctrl_handler_init(hdl, 1);
dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
- 0, AK7375_MAX_FOCUS_POS, AK7375_FOCUS_STEPS, 0);
+ 0, cdef->focus_pos_max, cdef->focus_steps, 0);
if (hdl->error)
dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
@@ -153,6 +171,8 @@ static int ak7375_probe(struct i2c_client *client)
if (!ak7375_dev)
return -ENOMEM;
+ ak7375_dev->cdef = device_get_match_data(&client->dev);
+
for (i = 0; i < ARRAY_SIZE(ak7375_supply_names); i++)
ak7375_dev->supplies[i].supply = ak7375_supply_names[i];
@@ -206,30 +226,31 @@ static void ak7375_remove(struct i2c_client *client)
/*
* This function sets the vcm position, so it consumes least current
- * The lens position is gradually moved in units of AK7375_CTRL_STEPS,
+ * The lens position is gradually moved in units of ctrl_steps,
* to make the movements smoothly.
*/
static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
+ const struct ak73xx_chipdef *cdef = ak7375_dev->cdef;
int ret, val;
if (!ak7375_dev->active)
return 0;
- for (val = ak7375_dev->focus->val & ~(AK7375_CTRL_STEPS - 1);
- val >= 0; val -= AK7375_CTRL_STEPS) {
- ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_POSITION,
- val << 4, 2);
+ for (val = ak7375_dev->focus->val & ~(cdef->ctrl_steps - 1);
+ val >= 0; val -= cdef->ctrl_steps) {
+ ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position,
+ val << cdef->shift_pos, 2);
if (ret)
dev_err_once(dev, "%s I2C failure: %d\n",
__func__, ret);
- usleep_range(AK7375_CTRL_DELAY_US, AK7375_CTRL_DELAY_US + 10);
+ usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10);
}
- ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_CONT,
- AK7375_MODE_STANDBY, 1);
+ ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
+ cdef->mode_standby, 1);
if (ret)
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
@@ -246,13 +267,14 @@ static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
/*
* This function sets the vcm position to the value set by the user
* through v4l2_ctrl_ops s_ctrl handler
- * The lens position is gradually moved in units of AK7375_CTRL_STEPS,
+ * The lens position is gradually moved in units of ctrl_steps,
* to make the movements smoothly.
*/
static int __maybe_unused ak7375_vcm_resume(struct device *dev)
{
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ak7375_device *ak7375_dev = sd_to_ak7375_vcm(sd);
+ const struct ak73xx_chipdef *cdef = ak7375_dev->cdef;
int ret, val;
if (ak7375_dev->active)
@@ -264,24 +286,24 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
return ret;
/* Wait for vcm to become ready */
- usleep_range(AK7375_POWER_DELAY_US, AK7375_POWER_DELAY_US + 500);
+ usleep_range(cdef->power_delay_us, cdef->power_delay_us + 500);
- ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_CONT,
- AK7375_MODE_ACTIVE, 1);
+ ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
+ cdef->mode_active, 1);
if (ret) {
dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
return ret;
}
- for (val = ak7375_dev->focus->val % AK7375_CTRL_STEPS;
+ for (val = ak7375_dev->focus->val % cdef->ctrl_steps;
val <= ak7375_dev->focus->val;
- val += AK7375_CTRL_STEPS) {
- ret = ak7375_i2c_write(ak7375_dev, AK7375_REG_POSITION,
- val << 4, 2);
+ val += cdef->ctrl_steps) {
+ ret = ak7375_i2c_write(ak7375_dev, cdef->reg_position,
+ val << cdef->shift_pos, 2);
if (ret)
dev_err_ratelimited(dev, "%s I2C failure: %d\n",
__func__, ret);
- usleep_range(AK7375_CTRL_DELAY_US, AK7375_CTRL_DELAY_US + 10);
+ usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10);
}
ak7375_dev->active = true;
@@ -290,7 +312,7 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
}
static const struct of_device_id ak7375_of_table[] = {
- { .compatible = "asahi-kasei,ak7375" },
+ { .compatible = "asahi-kasei,ak7375", .data = &ak7375_cdef, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ak7375_of_table);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support
2023-11-01 10:22 [PATCH 1/3] media: i2c: ak7375: Prepare for supporting another chip Vincent Knecht
@ 2023-11-01 10:22 ` Vincent Knecht
2023-11-01 15:10 ` Conor Dooley
2023-11-01 10:22 ` [PATCH 3/3] media: i2c: ak7375: Add support for ak7345 Vincent Knecht
1 sibling, 1 reply; 6+ messages in thread
From: Vincent Knecht @ 2023-11-01 10:22 UTC (permalink / raw)
To: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
Cc: Vincent Knecht
Document AK7345 bindings.
Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org>
---
.../devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml b/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
index 22a810fc7222..fe312cc6a873 100644
--- a/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
@@ -15,7 +15,9 @@ description:
properties:
compatible:
- const: asahi-kasei,ak7375
+ enum:
+ - asahi-kasei,ak7345
+ - asahi-kasei,ak7375
reg:
maxItems: 1
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support
2023-11-01 10:22 ` [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support Vincent Knecht
@ 2023-11-01 15:10 ` Conor Dooley
2023-11-01 15:29 ` Vincent Knecht
0 siblings, 1 reply; 6+ messages in thread
From: Conor Dooley @ 2023-11-01 15:10 UTC (permalink / raw)
To: Vincent Knecht
Cc: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1218 bytes --]
On Wed, Nov 01, 2023 at 11:22:56AM +0100, Vincent Knecht wrote:
> Document AK7345 bindings.
The commit message should mention why this device is incompatible with
the 7375. Something like
"Document the ak7345 voice coil motor actuator. Similar to the ak7375,
this model has 4 unilateral phase detractors instead of 8."
Otherwise,
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Cheers,
Conor.
>
> Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org>
> ---
> .../devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml b/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
> index 22a810fc7222..fe312cc6a873 100644
> --- a/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
> +++ b/Documentation/devicetree/bindings/media/i2c/asahi-kasei,ak7375.yaml
> @@ -15,7 +15,9 @@ description:
>
> properties:
> compatible:
> - const: asahi-kasei,ak7375
> + enum:
> + - asahi-kasei,ak7345
> + - asahi-kasei,ak7375
>
> reg:
> maxItems: 1
> --
> 2.41.0
>
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support
2023-11-01 15:10 ` Conor Dooley
@ 2023-11-01 15:29 ` Vincent Knecht
2023-11-01 15:33 ` Conor Dooley
0 siblings, 1 reply; 6+ messages in thread
From: Vincent Knecht @ 2023-11-01 15:29 UTC (permalink / raw)
To: Conor Dooley
Cc: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
Le mercredi 01 novembre 2023 à 15:10 +0000, Conor Dooley a écrit :
> On Wed, Nov 01, 2023 at 11:22:56AM +0100, Vincent Knecht wrote:
> > Document AK7345 bindings.
>
> The commit message should mention why this device is incompatible with
> the 7375. Something like
>
> "Document the ak7345 voice coil motor actuator. Similar to the ak7375,
> this model has 4 unilateral phase detractors instead of 8."
>
> Otherwise,
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
>
> Cheers,
> Conor.
Thank you for the review!
I don't know anything about phase detractors, nor any other details
(having found no datasheets for either of these ICs)
apart what could be infered from vendor/downstream drivers
like in the commit text for patch 3/3...
So I guess I'll send a v2 with a commit text along these lines :
Document AK7345 bindings.
Compared to AK7375, it has only 9 bits position values (instead of 12),
20 ms power-up delay (instead of 10), and no known standby register setting.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support
2023-11-01 15:29 ` Vincent Knecht
@ 2023-11-01 15:33 ` Conor Dooley
0 siblings, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2023-11-01 15:33 UTC (permalink / raw)
To: Vincent Knecht
Cc: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1354 bytes --]
On Wed, Nov 01, 2023 at 04:29:20PM +0100, Vincent Knecht wrote:
> Le mercredi 01 novembre 2023 à 15:10 +0000, Conor Dooley a écrit :
> > On Wed, Nov 01, 2023 at 11:22:56AM +0100, Vincent Knecht wrote:
> > > Document AK7345 bindings.
> >
> > The commit message should mention why this device is incompatible with
> > the 7375. Something like
> >
> > "Document the ak7345 voice coil motor actuator. Similar to the ak7375,
> > this model has 4 unilateral phase detractors instead of 8."
> >
> > Otherwise,
> > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> >
> > Cheers,
> > Conor.
>
> Thank you for the review!
>
> I don't know anything about phase detractors, nor any other details
hah, that was just me putting techobabble in the example text rather
than using foo. See also:
https://www.youtube.com/watch?v=RXJKdh1KZ0w
> (having found no datasheets for either of these ICs)
> apart what could be infered from vendor/downstream drivers
> like in the commit text for patch 3/3...
>
> So I guess I'll send a v2 with a commit text along these lines :
> Document AK7345 bindings.
> Compared to AK7375, it has only 9 bits position values (instead of 12),
> 20 ms power-up delay (instead of 10), and no known standby register setting.
Yah, that is the exact sort of information that is good to have, thanks.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] media: i2c: ak7375: Add support for ak7345
2023-11-01 10:22 [PATCH 1/3] media: i2c: ak7375: Prepare for supporting another chip Vincent Knecht
2023-11-01 10:22 ` [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support Vincent Knecht
@ 2023-11-01 10:22 ` Vincent Knecht
1 sibling, 0 replies; 6+ messages in thread
From: Vincent Knecht @ 2023-11-01 10:22 UTC (permalink / raw)
To: Tianshu Qiu, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Yassine Oudjana,
linux-media, devicetree, linux-kernel
Cc: Vincent Knecht
Add support for ak7345 VCM, which has 9 bits position values,
longer power-up delay, and no known standby register setting.
Might be compatible as-is with ak7348.
Tested on msm8916-alcatel-idol347 phone.
Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org>
---
drivers/media/i2c/ak7375.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/ak7375.c b/drivers/media/i2c/ak7375.c
index 3a14eff41531..9a2432cea3ff 100644
--- a/drivers/media/i2c/ak7375.c
+++ b/drivers/media/i2c/ak7375.c
@@ -16,6 +16,7 @@ struct ak73xx_chipdef {
u8 shift_pos;
u8 mode_active;
u8 mode_standby;
+ bool has_standby; /* Some chips may not have standby mode */
u16 focus_pos_max;
/*
* This sets the minimum granularity for the focus positions.
@@ -37,12 +38,26 @@ struct ak73xx_chipdef {
u16 power_delay_us;
};
+static const struct ak73xx_chipdef ak7345_cdef = {
+ .reg_position = 0x0,
+ .reg_cont = 0x2,
+ .shift_pos = 7, /* 9 bits position values, need to << 7 */
+ .mode_active = 0x0,
+ .has_standby = false,
+ .focus_pos_max = 511,
+ .focus_steps = 1,
+ .ctrl_steps = 16,
+ .ctrl_delay_us = 1000,
+ .power_delay_us = 20000,
+};
+
static const struct ak73xx_chipdef ak7375_cdef = {
.reg_position = 0x0,
.reg_cont = 0x2,
.shift_pos = 4, /* 12 bits position values, need to << 4 */
.mode_active = 0x0,
.mode_standby = 0x40,
+ .has_standby = true,
.focus_pos_max = 4095,
.focus_steps = 1,
.ctrl_steps = 64,
@@ -249,10 +264,12 @@ static int __maybe_unused ak7375_vcm_suspend(struct device *dev)
usleep_range(cdef->ctrl_delay_us, cdef->ctrl_delay_us + 10);
}
- ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
- cdef->mode_standby, 1);
- if (ret)
- dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
+ if (cdef->has_standby) {
+ ret = ak7375_i2c_write(ak7375_dev, cdef->reg_cont,
+ cdef->mode_standby, 1);
+ if (ret)
+ dev_err(dev, "%s I2C failure: %d\n", __func__, ret);
+ }
ret = regulator_bulk_disable(ARRAY_SIZE(ak7375_supply_names),
ak7375_dev->supplies);
@@ -312,6 +329,7 @@ static int __maybe_unused ak7375_vcm_resume(struct device *dev)
}
static const struct of_device_id ak7375_of_table[] = {
+ { .compatible = "asahi-kasei,ak7345", .data = &ak7345_cdef, },
{ .compatible = "asahi-kasei,ak7375", .data = &ak7375_cdef, },
{ /* sentinel */ }
};
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-11-01 15:33 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-01 10:22 [PATCH 1/3] media: i2c: ak7375: Prepare for supporting another chip Vincent Knecht
2023-11-01 10:22 ` [PATCH 2/3] media: dt-bindings: ak7375: Add ak7345 support Vincent Knecht
2023-11-01 15:10 ` Conor Dooley
2023-11-01 15:29 ` Vincent Knecht
2023-11-01 15:33 ` Conor Dooley
2023-11-01 10:22 ` [PATCH 3/3] media: i2c: ak7375: Add support for ak7345 Vincent Knecht
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox