... | ... | ||
---|---|---|---|
12 | 12 | ||
13 | Regards, | 13 | Regards, |
14 | Benjamin | 14 | Benjamin |
15 | 15 | ||
16 | --- | 16 | --- |
17 | Changes in v4: | ||
18 | - Fix data-lanes syntax in binding | ||
19 | - Link to v3: https://lore.kernel.org/r/20250402-b4-vd55g1-v3-0-393985404759@foss.st.com | ||
20 | |||
21 | Changes in v3: | ||
22 | - Add maxItems to data-lanes in binding | ||
23 | - Drop redondant 'binding' in binding commit message | ||
24 | - Link to v2: https://lore.kernel.org/r/20250401-b4-vd55g1-v2-0-0c8ab8a48c55@foss.st.com | ||
25 | |||
26 | Changes in v2: | ||
27 | - Fix device tree binding mistakes | ||
28 | - Drop linux media git from MAINTAINERS file | ||
29 | - Fix coding style mistakes | ||
30 | - Drop vd55g1_err_probe wrapper | ||
31 | - Fix 32bits build | ||
32 | - Fix config symbol help paragraph being too short for checkpatch | ||
33 | - Link to v1: https://lore.kernel.org/r/20250328-b4-vd55g1-v1-0-8d16b4a79f29@foss.st.com | ||
34 | |||
35 | --- | ||
17 | Benjamin Mugnier (2): | 36 | Benjamin Mugnier (2): |
18 | media: dt-bindings: Add ST VD55G1 camera sensor binding | 37 | media: dt-bindings: Add ST VD55G1 camera sensor |
19 | media: i2c: Add driver for ST VD55G1 camera sensor | 38 | media: i2c: Add driver for ST VD55G1 camera sensor |
20 | 39 | ||
21 | .../devicetree/bindings/media/i2c/st,vd55g1.yaml | 135 ++ | 40 | .../devicetree/bindings/media/i2c/st,vd55g1.yaml | 132 ++ |
22 | MAINTAINERS | 10 + | 41 | MAINTAINERS | 9 + |
23 | drivers/media/i2c/Kconfig | 8 + | 42 | drivers/media/i2c/Kconfig | 11 + |
24 | drivers/media/i2c/Makefile | 1 + | 43 | drivers/media/i2c/Makefile | 1 + |
25 | drivers/media/i2c/vd55g1.c | 2001 ++++++++++++++++++++ | 44 | drivers/media/i2c/vd55g1.c | 1993 ++++++++++++++++++++ |
26 | 5 files changed, 2155 insertions(+) | 45 | 5 files changed, 2146 insertions(+) |
27 | --- | 46 | --- |
28 | base-commit: b2c4bf0c102084e77ed1b12090d77a76469a6814 | 47 | base-commit: b2c4bf0c102084e77ed1b12090d77a76469a6814 |
29 | change-id: 20250225-b4-vd55g1-bdb90dbe39b3 | 48 | change-id: 20250225-b4-vd55g1-bdb90dbe39b3 |
30 | 49 | ||
31 | Best regards, | 50 | Best regards, |
32 | -- | 51 | -- |
33 | Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 52 | Benjamin Mugnier <benjamin.mugnier@foss.st.com> | diff view generated by jsdifflib |
1 | Also update MAINTAINERS file accordingly. | 1 | Also update MAINTAINERS file accordingly. |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 3 | Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com> |
4 | --- | 4 | --- |
5 | .../devicetree/bindings/media/i2c/st,vd55g1.yaml | 135 +++++++++++++++++++++ | 5 | .../devicetree/bindings/media/i2c/st,vd55g1.yaml | 132 +++++++++++++++++++++ |
6 | MAINTAINERS | 8 ++ | 6 | MAINTAINERS | 7 ++ |
7 | 2 files changed, 143 insertions(+) | 7 | 2 files changed, 139 insertions(+) |
8 | 8 | ||
9 | diff --git a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml | 9 | diff --git a/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml b/Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml |
10 | new file mode 100644 | 10 | new file mode 100644 |
11 | index XXXXXXX..XXXXXXX | 11 | index XXXXXXX..XXXXXXX |
12 | --- /dev/null | 12 | --- /dev/null |
... | ... | ||
36 | +allOf: | 36 | +allOf: |
37 | + - $ref: /schemas/media/video-interface-devices.yaml# | 37 | + - $ref: /schemas/media/video-interface-devices.yaml# |
38 | + | 38 | + |
39 | +properties: | 39 | +properties: |
40 | + compatible: | 40 | + compatible: |
41 | + const: st,st-vd55g1 | 41 | + const: st,vd55g1 |
42 | + | 42 | + |
43 | + reg: | 43 | + reg: |
44 | + maxItems: 1 | 44 | + maxItems: 1 |
45 | + | 45 | + |
46 | + clocks: | 46 | + clocks: |
... | ... | ||
80 | + $ref: /schemas/media/video-interfaces.yaml# | 80 | + $ref: /schemas/media/video-interfaces.yaml# |
81 | + unevaluatedProperties: false | 81 | + unevaluatedProperties: false |
82 | + | 82 | + |
83 | + properties: | 83 | + properties: |
84 | + data-lanes: | 84 | + data-lanes: |
85 | + description: | ||
86 | + VD55G1 only has one data lane, and must be 1. | ||
87 | + maxItems: 1 | ||
88 | + items: | 85 | + items: |
89 | + const: 1 | 86 | + - const: 1 |
90 | + | 87 | + |
91 | + link-frequencies: | 88 | + link-frequencies: |
92 | + maxItems: 1 | 89 | + maxItems: 1 |
93 | + items: | 90 | + items: |
94 | + minimum: 125000000 | 91 | + minimum: 125000000 |
... | ... | ||
158 | +ST VD55G1 DRIVER | 155 | +ST VD55G1 DRIVER |
159 | +M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 156 | +M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> |
160 | +M: Sylvain Petinot <sylvain.petinot@foss.st.com> | 157 | +M: Sylvain Petinot <sylvain.petinot@foss.st.com> |
161 | +L: linux-media@vger.kernel.org | 158 | +L: linux-media@vger.kernel.org |
162 | +S: Maintained | 159 | +S: Maintained |
163 | +T: git git://linuxtv.org/media.git | ||
164 | +F: Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml | 160 | +F: Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml |
165 | + | 161 | + |
166 | ST VGXY61 DRIVER | 162 | ST VGXY61 DRIVER |
167 | M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 163 | M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> |
168 | M: Sylvain Petinot <sylvain.petinot@foss.st.com> | 164 | M: Sylvain Petinot <sylvain.petinot@foss.st.com> |
169 | 165 | ||
170 | -- | 166 | -- |
171 | 2.25.1 | 167 | 2.25.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
11 | Add driver source code to MAINTAINERS file. | 11 | Add driver source code to MAINTAINERS file. |
12 | 12 | ||
13 | Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 13 | Signed-off-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com> |
14 | --- | 14 | --- |
15 | MAINTAINERS | 2 + | 15 | MAINTAINERS | 2 + |
16 | drivers/media/i2c/Kconfig | 8 + | 16 | drivers/media/i2c/Kconfig | 11 + |
17 | drivers/media/i2c/Makefile | 1 + | 17 | drivers/media/i2c/Makefile | 1 + |
18 | drivers/media/i2c/vd55g1.c | 2001 ++++++++++++++++++++++++++++++++++++++++++++ | 18 | drivers/media/i2c/vd55g1.c | 1993 ++++++++++++++++++++++++++++++++++++++++++++ |
19 | 4 files changed, 2012 insertions(+) | 19 | 4 files changed, 2007 insertions(+) |
20 | 20 | ||
21 | diff --git a/MAINTAINERS b/MAINTAINERS | 21 | diff --git a/MAINTAINERS b/MAINTAINERS |
22 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/MAINTAINERS | 23 | --- a/MAINTAINERS |
24 | +++ b/MAINTAINERS | 24 | +++ b/MAINTAINERS |
25 | @@ -XXX,XX +XXX,XX @@ L: linux-media@vger.kernel.org | 25 | @@ -XXX,XX +XXX,XX @@ M: Sylvain Petinot <sylvain.petinot@foss.st.com> |
26 | L: linux-media@vger.kernel.org | ||
26 | S: Maintained | 27 | S: Maintained |
27 | T: git git://linuxtv.org/media.git | ||
28 | F: Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml | 28 | F: Documentation/devicetree/bindings/media/i2c/st,vd55g1.yaml |
29 | +F: drivers/media/i2c/vd55g1.c | 29 | +F: drivers/media/i2c/vd55g1.c |
30 | 30 | ||
31 | ST VGXY61 DRIVER | 31 | ST VGXY61 DRIVER |
32 | M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> | 32 | M: Benjamin Mugnier <benjamin.mugnier@foss.st.com> |
... | ... | ||
51 | + select V4L2_CCI_I2C | 51 | + select V4L2_CCI_I2C |
52 | + depends on OF && GPIOLIB | 52 | + depends on OF && GPIOLIB |
53 | + help | 53 | + help |
54 | + This is a Video4Linux2 sensor driver for the ST VD55G1 | 54 | + This is a Video4Linux2 sensor driver for the ST VD55G1 |
55 | + camera sensor. | 55 | + camera sensor. |
56 | + | ||
57 | + To compile this driver as a module, choose M here: the | ||
58 | + module will be called vd55g1. | ||
56 | + | 59 | + |
57 | config VIDEO_VGXY61 | 60 | config VIDEO_VGXY61 |
58 | tristate "ST VGXY61 sensor support" | 61 | tristate "ST VGXY61 sensor support" |
59 | select V4L2_CCI_I2C | 62 | select V4L2_CCI_I2C |
60 | diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile | 63 | diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile |
... | ... | ||
797 | + | 800 | + |
798 | +static int vd55g1_prepare_clock_tree(struct vd55g1 *sensor) | 801 | +static int vd55g1_prepare_clock_tree(struct vd55g1 *sensor) |
799 | +{ | 802 | +{ |
800 | + struct i2c_client *client = sensor->i2c_client; | 803 | + struct i2c_client *client = sensor->i2c_client; |
801 | + /* Double data rate */ | 804 | + /* Double data rate */ |
802 | + u64 mipi_freq = link_freq[0] * 2; | 805 | + u32 mipi_freq = link_freq[0] * 2; |
803 | + u32 sys_clk, mipi_div, pixel_div; | 806 | + u32 sys_clk, mipi_div, pixel_div; |
804 | + int ret = 0; | 807 | + int ret = 0; |
805 | + | 808 | + |
806 | + if (sensor->xclk_freq < 6 * HZ_PER_MHZ || | 809 | + if (sensor->xclk_freq < 6 * HZ_PER_MHZ || |
807 | + sensor->xclk_freq > 27 * HZ_PER_MHZ) { | 810 | + sensor->xclk_freq > 27 * HZ_PER_MHZ) { |
... | ... | ||
812 | + } | 815 | + } |
813 | + | 816 | + |
814 | + if (mipi_freq < 250 * HZ_PER_MHZ || | 817 | + if (mipi_freq < 250 * HZ_PER_MHZ || |
815 | + mipi_freq > 1200 * HZ_PER_MHZ) { | 818 | + mipi_freq > 1200 * HZ_PER_MHZ) { |
816 | + dev_err(&client->dev, | 819 | + dev_err(&client->dev, |
817 | + "Only 250Mhz-1200Mhz link frequency range supported. Provided %llu MHz\n", | 820 | + "Only 250Mhz-1200Mhz link frequency range supported. Provided %lu MHz\n", |
818 | + mipi_freq / HZ_PER_MHZ); | 821 | + mipi_freq / HZ_PER_MHZ); |
819 | + return -EINVAL; | 822 | + return -EINVAL; |
820 | + } | 823 | + } |
821 | + | 824 | + |
822 | + if (mipi_freq <= 300 * HZ_PER_MHZ) | 825 | + if (mipi_freq <= 300 * HZ_PER_MHZ) |
... | ... | ||
1949 | + v4l2_subdev_cleanup(&sensor->sd); | 1952 | + v4l2_subdev_cleanup(&sensor->sd); |
1950 | + media_entity_cleanup(&sensor->sd.entity); | 1953 | + media_entity_cleanup(&sensor->sd.entity); |
1951 | + v4l2_ctrl_handler_free(sensor->sd.ctrl_handler); | 1954 | + v4l2_ctrl_handler_free(sensor->sd.ctrl_handler); |
1952 | +} | 1955 | +} |
1953 | + | 1956 | + |
1954 | +static int vd55g1_err_probe(struct device *dev, int ret, char *msg) | ||
1955 | +{ | ||
1956 | + return dev_err_probe(dev, ret, msg); | ||
1957 | +} | ||
1958 | + | ||
1959 | +static int vd55g1_probe(struct i2c_client *client) | 1957 | +static int vd55g1_probe(struct i2c_client *client) |
1960 | +{ | 1958 | +{ |
1961 | + struct device *dev = &client->dev; | 1959 | + struct device *dev = &client->dev; |
1962 | + struct vd55g1 *sensor; | 1960 | + struct vd55g1 *sensor; |
1963 | + int ret; | 1961 | + int ret; |
... | ... | ||
1969 | + v4l2_i2c_subdev_init(&sensor->sd, client, &vd55g1_subdev_ops); | 1967 | + v4l2_i2c_subdev_init(&sensor->sd, client, &vd55g1_subdev_ops); |
1970 | + sensor->i2c_client = client; | 1968 | + sensor->i2c_client = client; |
1971 | + | 1969 | + |
1972 | + ret = vd55g1_parse_dt(sensor); | 1970 | + ret = vd55g1_parse_dt(sensor); |
1973 | + if (ret) | 1971 | + if (ret) |
1974 | + return vd55g1_err_probe(dev, ret, | 1972 | + return dev_err_probe(dev, ret, "Failed to parse Device Tree."); |
1975 | + "Failed to parse Device Tree."); | ||
1976 | + | 1973 | + |
1977 | + /* Get (and check) resources : power regs, ext clock, reset gpio */ | 1974 | + /* Get (and check) resources : power regs, ext clock, reset gpio */ |
1978 | + ret = vd55g1_get_regulators(sensor); | 1975 | + ret = vd55g1_get_regulators(sensor); |
1979 | + if (ret) | 1976 | + if (ret) |
1980 | + return vd55g1_err_probe(dev, ret, "Failed to get regulators."); | 1977 | + return dev_err_probe(dev, ret, "Failed to get regulators."); |
1981 | + | 1978 | + |
1982 | + sensor->xclk = devm_clk_get(dev, NULL); | 1979 | + sensor->xclk = devm_clk_get(dev, NULL); |
1983 | + if (IS_ERR(sensor->xclk)) { | 1980 | + if (IS_ERR(sensor->xclk)) |
1984 | + return vd55g1_err_probe(dev, PTR_ERR(sensor->xclk), | 1981 | + return dev_err_probe(dev, PTR_ERR(sensor->xclk), |
1985 | + "Failed to get xclk."); | 1982 | + "Failed to get xclk."); |
1986 | + } | 1983 | + |
1987 | + sensor->xclk_freq = clk_get_rate(sensor->xclk); | 1984 | + sensor->xclk_freq = clk_get_rate(sensor->xclk); |
1988 | + ret = vd55g1_prepare_clock_tree(sensor); | 1985 | + ret = vd55g1_prepare_clock_tree(sensor); |
1989 | + if (ret) | 1986 | + if (ret) |
1990 | + return ret; | 1987 | + return ret; |
1991 | + | 1988 | + |
1992 | + sensor->reset_gpio = | 1989 | + sensor->reset_gpio = devm_gpiod_get_optional(dev, "reset", |
1993 | + devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); | 1990 | + GPIOD_OUT_HIGH); |
1994 | + if (IS_ERR(sensor->reset_gpio)) | 1991 | + if (IS_ERR(sensor->reset_gpio)) |
1995 | + return vd55g1_err_probe(dev, PTR_ERR(sensor->reset_gpio), | 1992 | + return dev_err_probe(dev, PTR_ERR(sensor->reset_gpio), |
1996 | + "Failed to get reset gpio."); | 1993 | + "Failed to get reset gpio."); |
1997 | + | 1994 | + |
1998 | + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); | 1995 | + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); |
1999 | + if (IS_ERR(sensor->regmap)) | 1996 | + if (IS_ERR(sensor->regmap)) |
2000 | + return vd55g1_err_probe(dev, PTR_ERR(sensor->regmap), | 1997 | + return dev_err_probe(dev, PTR_ERR(sensor->regmap), |
2001 | + "Failed to init regmap."); | 1998 | + "Failed to init regmap."); |
2002 | + | 1999 | + |
2003 | + /* Detect if sensor is present and if its revision is supported */ | 2000 | + /* Detect if sensor is present and if its revision is supported */ |
2004 | + ret = vd55g1_power_on(dev); | 2001 | + ret = vd55g1_power_on(dev); |
2005 | + if (ret) | 2002 | + if (ret) |
2006 | + return ret; | 2003 | + return ret; |
... | ... | ||
2022 | + pm_runtime_get_noresume(dev); | 2019 | + pm_runtime_get_noresume(dev); |
2023 | + pm_runtime_enable(dev); | 2020 | + pm_runtime_enable(dev); |
2024 | + pm_runtime_set_autosuspend_delay(dev, 4000); | 2021 | + pm_runtime_set_autosuspend_delay(dev, 4000); |
2025 | + pm_runtime_use_autosuspend(dev); | 2022 | + pm_runtime_use_autosuspend(dev); |
2026 | + pm_runtime_mark_last_busy(dev); | 2023 | + pm_runtime_mark_last_busy(dev); |
2027 | + | ||
2028 | + dev_dbg(dev, "vd55g1 probe successfully"); | ||
2029 | + | 2024 | + |
2030 | + return 0; | 2025 | + return 0; |
2031 | + | 2026 | + |
2032 | +err_subdev: | 2027 | +err_subdev: |
2033 | + vd55g1_subdev_cleanup(sensor); | 2028 | + vd55g1_subdev_cleanup(sensor); |
... | ... | diff view generated by jsdifflib |