Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-5.18-2.6-signed' of git://linuxtv.org/sailus/media_tree into media_stage

Even yet more V4L2 patches for 5.18

* tag 'for-5.18-2.6-signed' of git://linuxtv.org/sailus/media_tree:
media: i2c: Fix pixel array positions in ov8865
media: adv7183: Convert to GPIO descriptors
media: m5mols: Convert to use GPIO descriptors
media: noon010p30: Convert to use GPIO descriptors
media: mt9m111: Drop unused include
media: adv7511: Drop unused include
media: i2c: isl7998x: Add driver for Intersil ISL7998x
media: dt-bindings: Add Intersil ISL79987 DT bindings
media: media-entity: Clarify media_entity_cleanup() usage
media: i2c: imx274: Drop surplus includes
media: i2c: ccs: Drop unused include
v4l: fwnode: Remove now-redundant loop from v4l2_fwnode_parse_reference()
v4l: fwnode: Drop redunant -ENODATA check in property reference parsing
media: media-entity: Simplify media_pipeline_start()
media: media-entity: Add media_pad_is_streaming() helper function
media: Add a driver for the og01a1b camera sensor
media: i2c: ov5648: Fix lockdep error
media: ov5640: Fix set format, v4l2_mbus_pixelcode not updated

Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

+3063 -173
+113
Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/media/i2c/isil,isl79987.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Intersil ISL79987 Analog to MIPI CSI-2 decoder 8 + 9 + maintainers: 10 + - Michael Tretter <m.tretter@pengutronix.de> 11 + - Marek Vasut <marex@denx.de> 12 + 13 + description: 14 + The Intersil ISL79987 is an analog to MIPI CSI-2 decoder which is capable of 15 + receiving up to four analog stream and multiplexing them into up to four MIPI 16 + CSI-2 virtual channels, using one MIPI clock lane and 1/2 data lanes. 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - isil,isl79987 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + reset-gpios: 27 + maxItems: 1 28 + description: 29 + A GPIO spec for the RSTB pin (active high) 30 + 31 + powerdown-gpios: 32 + maxItems: 1 33 + description: 34 + A GPIO spec for the Power Down pin (active high) 35 + 36 + ports: 37 + $ref: /schemas/graph.yaml#/properties/ports 38 + properties: 39 + port@0: 40 + $ref: /schemas/graph.yaml#/$defs/port-base 41 + unevaluatedProperties: false 42 + description: Output port 43 + 44 + properties: 45 + endpoint: 46 + $ref: /schemas/media/video-interfaces.yaml# 47 + unevaluatedProperties: false 48 + 49 + properties: 50 + data-lanes: 51 + minItems: 1 52 + maxItems: 2 53 + 54 + required: 55 + - data-lanes 56 + 57 + patternProperties: 58 + "^port@[1-4]$": 59 + $ref: /schemas/graph.yaml#/properties/port 60 + description: Input ports 61 + 62 + required: 63 + - port@0 64 + 65 + additionalProperties: false 66 + 67 + required: 68 + - compatible 69 + - reg 70 + - ports 71 + 72 + examples: 73 + - | 74 + #include <dt-bindings/gpio/gpio.h> 75 + 76 + i2c { 77 + #address-cells = <1>; 78 + #size-cells = <0>; 79 + 80 + isl7998x_mipi@44 { 81 + compatible = "isil,isl79987"; 82 + reg = <0x44>; 83 + powerdown-gpios = <&gpio3 27 GPIO_ACTIVE_HIGH>; 84 + reset-gpios = <&gpio3 28 GPIO_ACTIVE_HIGH>; 85 + 86 + ports { 87 + #address-cells = <1>; 88 + #size-cells = <0>; 89 + 90 + port@0 { 91 + reg = <0>; 92 + isl79987_out: endpoint { 93 + remote-endpoint = <&mipi_csi2_in>; 94 + data-lanes = <1 2>; 95 + }; 96 + }; 97 + 98 + port@1 { 99 + reg = <1>; 100 + endpoint { 101 + remote-endpoint = <&camera_0>; 102 + }; 103 + }; 104 + 105 + port@2 { 106 + reg = <2>; 107 + endpoint { 108 + remote-endpoint = <&camera_1>; 109 + }; 110 + }; 111 + }; 112 + }; 113 + };
+14
MAINTAINERS
··· 10006 10006 F: Documentation/devicetree/bindings/counter/interrupt-counter.yaml 10007 10007 F: drivers/counter/interrupt-cnt.c 10008 10008 10009 + INTERSIL ISL7998X VIDEO DECODER DRIVER 10010 + M: Michael Tretter <m.tretter@pengutronix.de> 10011 + R: Pengutronix Kernel Team <kernel@pengutronix.de> 10012 + L: linux-media@vger.kernel.org 10013 + S: Maintained 10014 + F: Documentation/devicetree/bindings/media/i2c/isil,isl79987.yaml 10015 + F: drivers/media/i2c/isl7998x.c 10016 + 10009 10017 INVENSENSE ICM-426xx IMU DRIVER 10010 10018 M: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com> 10011 10019 L: linux-iio@vger.kernel.org ··· 14192 14184 M: Harald Welte <laforge@gnumonks.org> 14193 14185 S: Maintained 14194 14186 F: drivers/char/pcmcia/cm4040_cs.* 14187 + 14188 + OMNIVISION OG01A1B SENSOR DRIVER 14189 + M: Shawn Tu <shawnx.tu@intel.com> 14190 + L: linux-media@vger.kernel.org 14191 + S: Maintained 14192 + F: drivers/media/i2c/og01a1b.c 14195 14193 14196 14194 OMNIVISION OV02A10 SENSOR DRIVER 14197 14195 M: Dongchun Zhu <dongchun.zhu@mediatek.com>
+23
drivers/media/i2c/Kconfig
··· 325 325 To compile this driver as a module, choose M here: the 326 326 module will be called bt866. 327 327 328 + config VIDEO_ISL7998X 329 + tristate "Intersil ISL7998x video decoder" 330 + depends on VIDEO_V4L2 && I2C 331 + depends on OF_GPIO 332 + select MEDIA_CONTROLLER 333 + select VIDEO_V4L2_SUBDEV_API 334 + help 335 + Support for Intersil ISL7998x analog to MIPI-CSI2 or 336 + BT.656 decoder. 337 + 328 338 config VIDEO_KS0127 329 339 tristate "KS0127 video decoder" 330 340 depends on VIDEO_V4L2 && I2C ··· 921 911 922 912 To compile this driver as a module, choose M here: the 923 913 module will be called imx412. 914 + 915 + config VIDEO_OG01A1B 916 + tristate "OmniVision OG01A1B sensor support" 917 + depends on I2C && VIDEO_V4L2 918 + select MEDIA_CONTROLLER 919 + select VIDEO_V4L2_SUBDEV_API 920 + select V4L2_FWNODE 921 + help 922 + This is a Video4Linux2 sensor driver for the OmniVision 923 + OG01A1B camera. 924 + 925 + To compile this driver as a module, choose M here: the 926 + module will be called og01a1b. 924 927 925 928 config VIDEO_OV02A10 926 929 tristate "OmniVision OV02A10 sensor support"
+2
drivers/media/i2c/Makefile
··· 64 64 obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o 65 65 obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o 66 66 obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o 67 + obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o 67 68 obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o 68 69 obj-$(CONFIG_VIDEO_OV08D10) += ov08d10.o 69 70 obj-$(CONFIG_VIDEO_OV2640) += ov2640.o ··· 134 133 obj-$(CONFIG_VIDEO_IMX335) += imx335.o 135 134 obj-$(CONFIG_VIDEO_IMX355) += imx355.o 136 135 obj-$(CONFIG_VIDEO_IMX412) += imx412.o 136 + obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o 137 137 obj-$(CONFIG_VIDEO_MAX9286) += max9286.o 138 138 obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o 139 139 obj-$(CONFIG_VIDEO_RDACM20) += rdacm20.o
+25 -26
drivers/media/i2c/adv7183.c
··· 7 7 8 8 #include <linux/delay.h> 9 9 #include <linux/errno.h> 10 - #include <linux/gpio.h> 10 + #include <linux/gpio/consumer.h> 11 11 #include <linux/i2c.h> 12 12 #include <linux/init.h> 13 13 #include <linux/module.h> ··· 28 28 v4l2_std_id std; /* Current set standard */ 29 29 u32 input; 30 30 u32 output; 31 - unsigned reset_pin; 32 - unsigned oe_pin; 31 + struct gpio_desc *reset_pin; 32 + struct gpio_desc *oe_pin; 33 33 struct v4l2_mbus_framefmt fmt; 34 34 }; 35 35 ··· 465 465 struct adv7183 *decoder = to_adv7183(sd); 466 466 467 467 if (enable) 468 - gpio_set_value(decoder->oe_pin, 0); 468 + gpiod_set_value(decoder->oe_pin, 1); 469 469 else 470 - gpio_set_value(decoder->oe_pin, 1); 470 + gpiod_set_value(decoder->oe_pin, 0); 471 471 udelay(1); 472 472 return 0; 473 473 } ··· 531 531 struct v4l2_subdev_format fmt = { 532 532 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 533 533 }; 534 - const unsigned *pin_array; 535 534 536 535 /* Check if the adapter supports the needed features */ 537 536 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) ··· 539 540 v4l_info(client, "chip found @ 0x%02x (%s)\n", 540 541 client->addr << 1, client->adapter->name); 541 542 542 - pin_array = client->dev.platform_data; 543 - if (pin_array == NULL) 544 - return -EINVAL; 545 - 546 543 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL); 547 544 if (decoder == NULL) 548 545 return -ENOMEM; 549 546 550 - decoder->reset_pin = pin_array[0]; 551 - decoder->oe_pin = pin_array[1]; 552 - 553 - if (devm_gpio_request_one(&client->dev, decoder->reset_pin, 554 - GPIOF_OUT_INIT_LOW, "ADV7183 Reset")) { 555 - v4l_err(client, "failed to request GPIO %d\n", decoder->reset_pin); 556 - return -EBUSY; 557 - } 558 - 559 - if (devm_gpio_request_one(&client->dev, decoder->oe_pin, 560 - GPIOF_OUT_INIT_HIGH, 561 - "ADV7183 Output Enable")) { 562 - v4l_err(client, "failed to request GPIO %d\n", decoder->oe_pin); 563 - return -EBUSY; 564 - } 547 + /* 548 + * Requesting high will assert reset, the line should be 549 + * flagged as active low in descriptor table or machine description. 550 + */ 551 + decoder->reset_pin = devm_gpiod_get(&client->dev, "reset", 552 + GPIOD_OUT_HIGH); 553 + if (IS_ERR(decoder->reset_pin)) 554 + return PTR_ERR(decoder->reset_pin); 555 + gpiod_set_consumer_name(decoder->reset_pin, "ADV7183 Reset"); 556 + /* 557 + * Requesting low will start with output disabled, the line should be 558 + * flagged as active low in descriptor table or machine description. 559 + */ 560 + decoder->oe_pin = devm_gpiod_get(&client->dev, "oe", 561 + GPIOD_OUT_LOW); 562 + if (IS_ERR(decoder->oe_pin)) 563 + return PTR_ERR(decoder->oe_pin); 564 + gpiod_set_consumer_name(decoder->reset_pin, "ADV7183 Output Enable"); 565 565 566 566 sd = &decoder->sd; 567 567 v4l2_i2c_subdev_init(sd, client, &adv7183_ops); ··· 592 594 /* reset chip */ 593 595 /* reset pulse width at least 5ms */ 594 596 mdelay(10); 595 - gpio_set_value(decoder->reset_pin, 1); 597 + /* De-assert reset line (descriptor tagged active low) */ 598 + gpiod_set_value(decoder->reset_pin, 0); 596 599 /* wait 5ms before any further i2c writes are performed */ 597 600 mdelay(5); 598 601
-1
drivers/media/i2c/adv7511-v4l2.c
··· 17 17 #include <linux/i2c.h> 18 18 #include <linux/delay.h> 19 19 #include <linux/videodev2.h> 20 - #include <linux/gpio.h> 21 20 #include <linux/workqueue.h> 22 21 #include <linux/hdmi.h> 23 22 #include <linux/v4l2-dv-timings.h>
-1
drivers/media/i2c/ccs/ccs-core.c
··· 17 17 #include <linux/delay.h> 18 18 #include <linux/device.h> 19 19 #include <linux/firmware.h> 20 - #include <linux/gpio.h> 21 20 #include <linux/gpio/consumer.h> 22 21 #include <linux/module.h> 23 22 #include <linux/pm_runtime.h>
-2
drivers/media/i2c/imx274.c
··· 11 11 12 12 #include <linux/clk.h> 13 13 #include <linux/delay.h> 14 - #include <linux/gpio.h> 15 14 #include <linux/gpio/consumer.h> 16 15 #include <linux/i2c.h> 17 16 #include <linux/init.h> 18 17 #include <linux/kernel.h> 19 18 #include <linux/module.h> 20 - #include <linux/of_gpio.h> 21 19 #include <linux/pm_runtime.h> 22 20 #include <linux/regmap.h> 23 21 #include <linux/regulator/consumer.h>
+1628
drivers/media/i2c/isl7998x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Intersil ISL7998x analog to MIPI CSI-2 or BT.656 decoder driver. 4 + * 5 + * Copyright (C) 2018-2019 Marek Vasut <marex@denx.de> 6 + * Copyright (C) 2021 Michael Tretter <kernel@pengutronix.de> 7 + */ 8 + 9 + #include <linux/bitfield.h> 10 + #include <linux/delay.h> 11 + #include <linux/gpio.h> 12 + #include <linux/i2c.h> 13 + #include <linux/module.h> 14 + #include <linux/of_graph.h> 15 + #include <linux/pm_runtime.h> 16 + #include <linux/regmap.h> 17 + #include <linux/slab.h> 18 + #include <linux/v4l2-mediabus.h> 19 + #include <linux/videodev2.h> 20 + 21 + #include <media/v4l2-async.h> 22 + #include <media/v4l2-common.h> 23 + #include <media/v4l2-ctrls.h> 24 + #include <media/v4l2-device.h> 25 + #include <media/v4l2-fwnode.h> 26 + #include <media/v4l2-ioctl.h> 27 + 28 + /* 29 + * This control allows to activate and deactivate the test pattern on 30 + * selected output channels. 31 + * This value is ISL7998x specific. 32 + */ 33 + #define V4L2_CID_TEST_PATTERN_CHANNELS (V4L2_CID_USER_ISL7998X_BASE + 0) 34 + 35 + /* 36 + * This control allows to specify the color of the test pattern. 37 + * This value is ISL7998x specific. 38 + */ 39 + #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_ISL7998X_BASE + 1) 40 + 41 + /* 42 + * This control allows to specify the bar pattern in the test pattern. 43 + * This value is ISL7998x specific. 44 + */ 45 + #define V4L2_CID_TEST_PATTERN_BARS (V4L2_CID_USER_ISL7998X_BASE + 2) 46 + 47 + #define ISL7998X_INPUTS 4 48 + 49 + #define ISL7998X_REG(page, reg) (((page) << 8) | (reg)) 50 + 51 + #define ISL7998X_REG_PN_SIZE 256 52 + #define ISL7998X_REG_PN_BASE(n) ((n) * ISL7998X_REG_PN_SIZE) 53 + 54 + #define ISL7998X_REG_PX_DEC_PAGE(page) ISL7998X_REG((page), 0xff) 55 + #define ISL7998X_REG_PX_DEC_PAGE_MASK 0xf 56 + #define ISL7998X_REG_P0_PRODUCT_ID_CODE ISL7998X_REG(0, 0x00) 57 + #define ISL7998X_REG_P0_PRODUCT_REV_CODE ISL7998X_REG(0, 0x01) 58 + #define ISL7998X_REG_P0_SW_RESET_CTL ISL7998X_REG(0, 0x02) 59 + #define ISL7998X_REG_P0_IO_BUFFER_CTL ISL7998X_REG(0, 0x03) 60 + #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_1 ISL7998X_REG(0, 0x04) 61 + #define ISL7998X_REG_P0_IO_PAD_PULL_EN_CTL ISL7998X_REG(0, 0x05) 62 + #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_2 ISL7998X_REG(0, 0x06) 63 + #define ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL ISL7998X_REG(0, 0x07) 64 + #define ISL7998X_REG_P0_CLK_CTL_1 ISL7998X_REG(0, 0x08) 65 + #define ISL7998X_REG_P0_CLK_CTL_2 ISL7998X_REG(0, 0x09) 66 + #define ISL7998X_REG_P0_CLK_CTL_3 ISL7998X_REG(0, 0x0a) 67 + #define ISL7998X_REG_P0_CLK_CTL_4 ISL7998X_REG(0, 0x0b) 68 + #define ISL7998X_REG_P0_MPP1_SYNC_CTL ISL7998X_REG(0, 0x0c) 69 + #define ISL7998X_REG_P0_MPP2_SYNC_CTL ISL7998X_REG(0, 0x0d) 70 + #define ISL7998X_REG_P0_IRQ_SYNC_CTL ISL7998X_REG(0, 0x0e) 71 + #define ISL7998X_REG_P0_INTERRUPT_STATUS ISL7998X_REG(0, 0x10) 72 + #define ISL7998X_REG_P0_CHAN_1_IRQ ISL7998X_REG(0, 0x11) 73 + #define ISL7998X_REG_P0_CHAN_2_IRQ ISL7998X_REG(0, 0x12) 74 + #define ISL7998X_REG_P0_CHAN_3_IRQ ISL7998X_REG(0, 0x13) 75 + #define ISL7998X_REG_P0_CHAN_4_IRQ ISL7998X_REG(0, 0x14) 76 + #define ISL7998X_REG_P0_SHORT_DIAG_IRQ ISL7998X_REG(0, 0x15) 77 + #define ISL7998X_REG_P0_CHAN_1_IRQ_EN ISL7998X_REG(0, 0x16) 78 + #define ISL7998X_REG_P0_CHAN_2_IRQ_EN ISL7998X_REG(0, 0x17) 79 + #define ISL7998X_REG_P0_CHAN_3_IRQ_EN ISL7998X_REG(0, 0x18) 80 + #define ISL7998X_REG_P0_CHAN_4_IRQ_EN ISL7998X_REG(0, 0x19) 81 + #define ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN ISL7998X_REG(0, 0x1a) 82 + #define ISL7998X_REG_P0_CHAN_1_STATUS ISL7998X_REG(0, 0x1b) 83 + #define ISL7998X_REG_P0_CHAN_2_STATUS ISL7998X_REG(0, 0x1c) 84 + #define ISL7998X_REG_P0_CHAN_3_STATUS ISL7998X_REG(0, 0x1d) 85 + #define ISL7998X_REG_P0_CHAN_4_STATUS ISL7998X_REG(0, 0x1e) 86 + #define ISL7998X_REG_P0_SHORT_DIAG_STATUS ISL7998X_REG(0, 0x1f) 87 + #define ISL7998X_REG_P0_CLOCK_DELAY ISL7998X_REG(0, 0x20) 88 + 89 + #define ISL7998X_REG_PX_DEC_INPUT_FMT(pg) ISL7998X_REG((pg), 0x02) 90 + #define ISL7998X_REG_PX_DEC_STATUS_1(pg) ISL7998X_REG((pg), 0x03) 91 + #define ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS BIT(7) 92 + #define ISL7998X_REG_PX_DEC_STATUS_1_HLOCK BIT(6) 93 + #define ISL7998X_REG_PX_DEC_STATUS_1_VLOCK BIT(3) 94 + #define ISL7998X_REG_PX_DEC_HS_DELAY_CTL(pg) ISL7998X_REG((pg), 0x04) 95 + #define ISL7998X_REG_PX_DEC_ANCTL(pg) ISL7998X_REG((pg), 0x06) 96 + #define ISL7998X_REG_PX_DEC_CROP_HI(pg) ISL7998X_REG((pg), 0x07) 97 + #define ISL7998X_REG_PX_DEC_VDELAY_LO(pg) ISL7998X_REG((pg), 0x08) 98 + #define ISL7998X_REG_PX_DEC_VACTIVE_LO(pg) ISL7998X_REG((pg), 0x09) 99 + #define ISL7998X_REG_PX_DEC_HDELAY_LO(pg) ISL7998X_REG((pg), 0x0a) 100 + #define ISL7998X_REG_PX_DEC_HACTIVE_LO(pg) ISL7998X_REG((pg), 0x0b) 101 + #define ISL7998X_REG_PX_DEC_CNTRL1(pg) ISL7998X_REG((pg), 0x0c) 102 + #define ISL7998X_REG_PX_DEC_CSC_CTL(pg) ISL7998X_REG((pg), 0x0d) 103 + #define ISL7998X_REG_PX_DEC_BRIGHT(pg) ISL7998X_REG((pg), 0x10) 104 + #define ISL7998X_REG_PX_DEC_CONTRAST(pg) ISL7998X_REG((pg), 0x11) 105 + #define ISL7998X_REG_PX_DEC_SHARPNESS(pg) ISL7998X_REG((pg), 0x12) 106 + #define ISL7998X_REG_PX_DEC_SAT_U(pg) ISL7998X_REG((pg), 0x13) 107 + #define ISL7998X_REG_PX_DEC_SAT_V(pg) ISL7998X_REG((pg), 0x14) 108 + #define ISL7998X_REG_PX_DEC_HUE(pg) ISL7998X_REG((pg), 0x15) 109 + #define ISL7998X_REG_PX_DEC_VERT_PEAK(pg) ISL7998X_REG((pg), 0x17) 110 + #define ISL7998X_REG_PX_DEC_CORING(pg) ISL7998X_REG((pg), 0x18) 111 + #define ISL7998X_REG_PX_DEC_SDT(pg) ISL7998X_REG((pg), 0x1c) 112 + #define ISL7998X_REG_PX_DEC_SDT_DET BIT(7) 113 + #define ISL7998X_REG_PX_DEC_SDT_NOW GENMASK(6, 4) 114 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD GENMASK(2, 0) 115 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M 0 116 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL 1 117 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM 2 118 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443 3 119 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M 4 120 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN 5 121 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60 6 122 + #define ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN 7 123 + #define ISL7998X_REG_PX_DEC_SDTR(pg) ISL7998X_REG((pg), 0x1d) 124 + #define ISL7998X_REG_PX_DEC_SDTR_ATSTART BIT(7) 125 + #define ISL7998X_REG_PX_DEC_CLMPG(pg) ISL7998X_REG((pg), 0x20) 126 + #define ISL7998X_REG_PX_DEC_IAGC(pg) ISL7998X_REG((pg), 0x21) 127 + #define ISL7998X_REG_PX_DEC_AGCGAIN(pg) ISL7998X_REG((pg), 0x22) 128 + #define ISL7998X_REG_PX_DEC_PEAKWT(pg) ISL7998X_REG((pg), 0x23) 129 + #define ISL7998X_REG_PX_DEC_CLMPL(pg) ISL7998X_REG((pg), 0x24) 130 + #define ISL7998X_REG_PX_DEC_SYNCT(pg) ISL7998X_REG((pg), 0x25) 131 + #define ISL7998X_REG_PX_DEC_MISSCNT(pg) ISL7998X_REG((pg), 0x26) 132 + #define ISL7998X_REG_PX_DEC_PCLAMP(pg) ISL7998X_REG((pg), 0x27) 133 + #define ISL7998X_REG_PX_DEC_VERT_CTL_1(pg) ISL7998X_REG((pg), 0x28) 134 + #define ISL7998X_REG_PX_DEC_VERT_CTL_2(pg) ISL7998X_REG((pg), 0x29) 135 + #define ISL7998X_REG_PX_DEC_CLR_KILL_LVL(pg) ISL7998X_REG((pg), 0x2a) 136 + #define ISL7998X_REG_PX_DEC_COMB_FILTER_CTL(pg) ISL7998X_REG((pg), 0x2b) 137 + #define ISL7998X_REG_PX_DEC_LUMA_DELAY(pg) ISL7998X_REG((pg), 0x2c) 138 + #define ISL7998X_REG_PX_DEC_MISC1(pg) ISL7998X_REG((pg), 0x2d) 139 + #define ISL7998X_REG_PX_DEC_MISC2(pg) ISL7998X_REG((pg), 0x2e) 140 + #define ISL7998X_REG_PX_DEC_MISC3(pg) ISL7998X_REG((pg), 0x2f) 141 + #define ISL7998X_REG_PX_DEC_MVSN(pg) ISL7998X_REG((pg), 0x30) 142 + #define ISL7998X_REG_PX_DEC_CSTATUS2(pg) ISL7998X_REG((pg), 0x31) 143 + #define ISL7998X_REG_PX_DEC_HFREF(pg) ISL7998X_REG((pg), 0x32) 144 + #define ISL7998X_REG_PX_DEC_CLMD(pg) ISL7998X_REG((pg), 0x33) 145 + #define ISL7998X_REG_PX_DEC_ID_DET_CTL(pg) ISL7998X_REG((pg), 0x34) 146 + #define ISL7998X_REG_PX_DEC_CLCNTL(pg) ISL7998X_REG((pg), 0x35) 147 + #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_1(pg) ISL7998X_REG((pg), 0x36) 148 + #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_2(pg) ISL7998X_REG((pg), 0x37) 149 + #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_3(pg) ISL7998X_REG((pg), 0x38) 150 + #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_4(pg) ISL7998X_REG((pg), 0x39) 151 + #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL(pg) ISL7998X_REG((pg), 0x3a) 152 + #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(pg) ISL7998X_REG((pg), 0x3b) 153 + #define ISL7998X_REG_PX_DEC_AFE_TST_MUX_CTL(pg) ISL7998X_REG((pg), 0x3c) 154 + #define ISL7998X_REG_PX_DEC_DATA_CONV(pg) ISL7998X_REG((pg), 0x3d) 155 + #define ISL7998X_REG_PX_DEC_INTERNAL_TEST(pg) ISL7998X_REG((pg), 0x3f) 156 + #define ISL7998X_REG_PX_DEC_H_DELAY_CTL(pg) ISL7998X_REG((pg), 0x43) 157 + #define ISL7998X_REG_PX_DEC_H_DELAY_II_HI(pg) ISL7998X_REG((pg), 0x44) 158 + #define ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(pg) ISL7998X_REG((pg), 0x45) 159 + 160 + #define ISL7998X_REG_PX_ACA_CTL_1(pg) ISL7998X_REG((pg), 0x80) 161 + #define ISL7998X_REG_PX_ACA_GAIN_CTL(pg) ISL7998X_REG((pg), 0x81) 162 + #define ISL7998X_REG_PX_ACA_Y_AVG_HI_LIMIT(pg) ISL7998X_REG((pg), 0x82) 163 + #define ISL7998X_REG_PX_ACA_Y_AVG_LO_LIMIT(pg) ISL7998X_REG((pg), 0x83) 164 + #define ISL7998X_REG_PX_ACA_Y_DET_THRESHOLD(pg) ISL7998X_REG((pg), 0x84) 165 + #define ISL7998X_REG_PX_ACA_BLACK_LVL(pg) ISL7998X_REG((pg), 0x85) 166 + #define ISL7998X_REG_PX_ACA_CENTER_LVL(pg) ISL7998X_REG((pg), 0x86) 167 + #define ISL7998X_REG_PX_ACA_WHITE_LVL(pg) ISL7998X_REG((pg), 0x87) 168 + #define ISL7998X_REG_PX_ACA_MEAN_OFF_LIMIT(pg) ISL7998X_REG((pg), 0x88) 169 + #define ISL7998X_REG_PX_ACA_MEAN_OFF_UPGAIN(pg) ISL7998X_REG((pg), 0x89) 170 + #define ISL7998X_REG_PX_ACA_MEAN_OFF_SLOPE(pg) ISL7998X_REG((pg), 0x8a) 171 + #define ISL7998X_REG_PX_ACA_MEAN_OFF_DNGAIN(pg) ISL7998X_REG((pg), 0x8b) 172 + #define ISL7998X_REG_PX_ACA_DELTA_CO_THRES(pg) ISL7998X_REG((pg), 0x8c) 173 + #define ISL7998X_REG_PX_ACA_DELTA_SLOPE(pg) ISL7998X_REG((pg), 0x8d) 174 + #define ISL7998X_REG_PX_ACA_LO_HI_AVG_THRES(pg) ISL7998X_REG((pg), 0x8e) 175 + #define ISL7998X_REG_PX_ACA_LO_MAX_LVL_CTL(pg) ISL7998X_REG((pg), 0x8f) 176 + #define ISL7998X_REG_PX_ACA_HI_MAX_LVL_CTL(pg) ISL7998X_REG((pg), 0x90) 177 + #define ISL7998X_REG_PX_ACA_LO_UPGAIN_CTL(pg) ISL7998X_REG((pg), 0x91) 178 + #define ISL7998X_REG_PX_ACA_LO_DNGAIN_CTL(pg) ISL7998X_REG((pg), 0x92) 179 + #define ISL7998X_REG_PX_ACA_HI_UPGAIN_CTL(pg) ISL7998X_REG((pg), 0x93) 180 + #define ISL7998X_REG_PX_ACA_HI_DNGAIN_CTL(pg) ISL7998X_REG((pg), 0x94) 181 + #define ISL7998X_REG_PX_ACA_LOPASS_FLT_COEF(pg) ISL7998X_REG((pg), 0x95) 182 + #define ISL7998X_REG_PX_ACA_PDF_INDEX(pg) ISL7998X_REG((pg), 0x96) 183 + #define ISL7998X_REG_PX_ACA_HIST_WIN_H_STT(pg) ISL7998X_REG((pg), 0x97) 184 + #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ1(pg) ISL7998X_REG((pg), 0x98) 185 + #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ2(pg) ISL7998X_REG((pg), 0x99) 186 + #define ISL7998X_REG_PX_ACA_HIST_WIN_V_STT(pg) ISL7998X_REG((pg), 0x9a) 187 + #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ1(pg) ISL7998X_REG((pg), 0x9b) 188 + #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(pg) ISL7998X_REG((pg), 0x9c) 189 + #define ISL7998X_REG_PX_ACA_Y_AVG(pg) ISL7998X_REG((pg), 0xa0) 190 + #define ISL7998X_REG_PX_ACA_Y_AVG_LIM(pg) ISL7998X_REG((pg), 0xa1) 191 + #define ISL7998X_REG_PX_ACA_LO_AVG(pg) ISL7998X_REG((pg), 0xa2) 192 + #define ISL7998X_REG_PX_ACA_HI_AVG(pg) ISL7998X_REG((pg), 0xa3) 193 + #define ISL7998X_REG_PX_ACA_Y_MAX(pg) ISL7998X_REG((pg), 0xa4) 194 + #define ISL7998X_REG_PX_ACA_Y_MIN(pg) ISL7998X_REG((pg), 0xa5) 195 + #define ISL7998X_REG_PX_ACA_MOFFSET(pg) ISL7998X_REG((pg), 0xa6) 196 + #define ISL7998X_REG_PX_ACA_LO_GAIN(pg) ISL7998X_REG((pg), 0xa7) 197 + #define ISL7998X_REG_PX_ACA_HI_GAIN(pg) ISL7998X_REG((pg), 0xa8) 198 + #define ISL7998X_REG_PX_ACA_LL_SLOPE(pg) ISL7998X_REG((pg), 0xa9) 199 + #define ISL7998X_REG_PX_ACA_LH_SLOPE(pg) ISL7998X_REG((pg), 0xaa) 200 + #define ISL7998X_REG_PX_ACA_HL_SLOPE(pg) ISL7998X_REG((pg), 0xab) 201 + #define ISL7998X_REG_PX_ACA_HH_SLOPE(pg) ISL7998X_REG((pg), 0xac) 202 + #define ISL7998X_REG_PX_ACA_X_LOW(pg) ISL7998X_REG((pg), 0xad) 203 + #define ISL7998X_REG_PX_ACA_X_MEAN(pg) ISL7998X_REG((pg), 0xae) 204 + #define ISL7998X_REG_PX_ACA_X_HIGH(pg) ISL7998X_REG((pg), 0xaf) 205 + #define ISL7998X_REG_PX_ACA_Y_LOW(pg) ISL7998X_REG((pg), 0xb0) 206 + #define ISL7998X_REG_PX_ACA_Y_MEAN(pg) ISL7998X_REG((pg), 0xb1) 207 + #define ISL7998X_REG_PX_ACA_Y_HIGH(pg) ISL7998X_REG((pg), 0xb2) 208 + #define ISL7998X_REG_PX_ACA_CTL_2(pg) ISL7998X_REG((pg), 0xb3) 209 + #define ISL7998X_REG_PX_ACA_CTL_3(pg) ISL7998X_REG((pg), 0xb4) 210 + #define ISL7998X_REG_PX_ACA_CTL_4(pg) ISL7998X_REG((pg), 0xb5) 211 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(pg) ISL7998X_REG((pg), 0xc0) 212 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_H(pg) ISL7998X_REG((pg), 0xc1) 213 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_L(pg) ISL7998X_REG((pg), 0xc2) 214 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_H(pg) ISL7998X_REG((pg), 0xc3) 215 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_L(pg) ISL7998X_REG((pg), 0xc4) 216 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_H(pg) ISL7998X_REG((pg), 0xc5) 217 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_L(pg) ISL7998X_REG((pg), 0xc6) 218 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_H(pg) ISL7998X_REG((pg), 0xc7) 219 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_L(pg) ISL7998X_REG((pg), 0xc8) 220 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_H(pg) ISL7998X_REG((pg), 0xc9) 221 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_L(pg) ISL7998X_REG((pg), 0xca) 222 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_H(pg) ISL7998X_REG((pg), 0xcb) 223 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_L(pg) ISL7998X_REG((pg), 0xcc) 224 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_H(pg) ISL7998X_REG((pg), 0xcd) 225 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_L(pg) ISL7998X_REG((pg), 0xce) 226 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_H(pg) ISL7998X_REG((pg), 0xcf) 227 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_L(pg) ISL7998X_REG((pg), 0xd0) 228 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_H(pg) ISL7998X_REG((pg), 0xd1) 229 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_L(pg) ISL7998X_REG((pg), 0xd2) 230 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_H(pg) ISL7998X_REG((pg), 0xd3) 231 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_L(pg) ISL7998X_REG((pg), 0xd4) 232 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_H(pg) ISL7998X_REG((pg), 0xd5) 233 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_L(pg) ISL7998X_REG((pg), 0xd6) 234 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_H(pg) ISL7998X_REG((pg), 0xd7) 235 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_L(pg) ISL7998X_REG((pg), 0xd8) 236 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_H(pg) ISL7998X_REG((pg), 0xd9) 237 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_L(pg) ISL7998X_REG((pg), 0xda) 238 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_H(pg) ISL7998X_REG((pg), 0xdb) 239 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_L(pg) ISL7998X_REG((pg), 0xdc) 240 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_H(pg) ISL7998X_REG((pg), 0xdd) 241 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_L(pg) ISL7998X_REG((pg), 0xde) 242 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_H(pg) ISL7998X_REG((pg), 0xdf) 243 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_L(pg) ISL7998X_REG((pg), 0xe0) 244 + #define ISL7998X_REG_PX_ACA_HIST_DATA_LO(pg) ISL7998X_REG((pg), 0xe1) 245 + #define ISL7998X_REG_PX_ACA_HIST_DATA_MID(pg) ISL7998X_REG((pg), 0xe2) 246 + #define ISL7998X_REG_PX_ACA_HIST_DATA_HI(pg) ISL7998X_REG((pg), 0xe3) 247 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_CLR(pg) ISL7998X_REG((pg), 0xe4) 248 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_CB_CLR(pg) ISL7998X_REG((pg), 0xe5) 249 + #define ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(pg) ISL7998X_REG((pg), 0xe6) 250 + #define ISL7998X_REG_PX_ACA_XFER_HIST_HOST(pg) ISL7998X_REG((pg), 0xe7) 251 + 252 + #define ISL7998X_REG_P5_LI_ENGINE_CTL ISL7998X_REG(5, 0x00) 253 + #define ISL7998X_REG_P5_LI_ENGINE_LINE_CTL ISL7998X_REG(5, 0x01) 254 + #define ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH ISL7998X_REG(5, 0x02) 255 + #define ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL ISL7998X_REG(5, 0x03) 256 + #define ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT ISL7998X_REG(5, 0x04) 257 + #define ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL ISL7998X_REG(5, 0x05) 258 + #define ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL ISL7998X_REG(5, 0x06) 259 + #define ISL7998X_REG_P5_MIPI_READ_START_CTL ISL7998X_REG(5, 0x07) 260 + #define ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL ISL7998X_REG(5, 0x08) 261 + #define ISL7998X_REG_P5_ONE_FIELD_MODE_CTL ISL7998X_REG(5, 0x09) 262 + #define ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR ISL7998X_REG(5, 0x0a) 263 + #define ISL7998X_REG_P5_TP_GEN_BAR_PATTERN ISL7998X_REG(5, 0x0b) 264 + #define ISL7998X_REG_P5_MIPI_PCNT_PSFRM ISL7998X_REG(5, 0x0c) 265 + #define ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL ISL7998X_REG(5, 0x0d) 266 + #define ISL7998X_REG_P5_MIPI_VBLANK_PSFRM ISL7998X_REG(5, 0x0e) 267 + #define ISL7998X_REG_P5_LI_ENGINE_CTL_2 ISL7998X_REG(5, 0x0f) 268 + #define ISL7998X_REG_P5_MIPI_WCNT_1 ISL7998X_REG(5, 0x10) 269 + #define ISL7998X_REG_P5_MIPI_WCNT_2 ISL7998X_REG(5, 0x11) 270 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1 ISL7998X_REG(5, 0x12) 271 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2 ISL7998X_REG(5, 0x13) 272 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3 ISL7998X_REG(5, 0x14) 273 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4 ISL7998X_REG(5, 0x15) 274 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5 ISL7998X_REG(5, 0x16) 275 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6 ISL7998X_REG(5, 0x17) 276 + #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1 ISL7998X_REG(5, 0x18) 277 + #define ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD ISL7998X_REG(5, 0x19) 278 + #define ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD ISL7998X_REG(5, 0x1a) 279 + #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2 ISL7998X_REG(5, 0x1b) 280 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7 ISL7998X_REG(5, 0x1c) 281 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8 ISL7998X_REG(5, 0x1d) 282 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9 ISL7998X_REG(5, 0x1e) 283 + #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_10 ISL7998X_REG(5, 0x1f) 284 + #define ISL7998X_REG_P5_TP_GEN_MIPI ISL7998X_REG(5, 0x20) 285 + #define ISL7998X_REG_P5_ESC_MODE_TIME_CTL ISL7998X_REG(5, 0x21) 286 + #define ISL7998X_REG_P5_AUTO_TEST_ERR_DET ISL7998X_REG(5, 0x22) 287 + #define ISL7998X_REG_P5_MIPI_TIMING ISL7998X_REG(5, 0x23) 288 + #define ISL7998X_REG_P5_PIC_HEIGHT_HIGH ISL7998X_REG(5, 0x24) 289 + #define ISL7998X_REG_P5_PIC_HEIGHT_LOW ISL7998X_REG(5, 0x25) 290 + #define ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL ISL7998X_REG(5, 0x26) 291 + #define ISL7998X_REG_P5_FIFO_THRSH_CNT_1 ISL7998X_REG(5, 0x28) 292 + #define ISL7998X_REG_P5_FIFO_THRSH_CNT_2 ISL7998X_REG(5, 0x29) 293 + #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1 ISL7998X_REG(5, 0x2a) 294 + #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2 ISL7998X_REG(5, 0x2b) 295 + #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_1 ISL7998X_REG(5, 0x2c) 296 + #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_2 ISL7998X_REG(5, 0x2d) 297 + #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_3 ISL7998X_REG(5, 0x2e) 298 + #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_4 ISL7998X_REG(5, 0x2f) 299 + #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1 ISL7998X_REG(5, 0x30) 300 + #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2 ISL7998X_REG(5, 0x31) 301 + #define ISL7998X_REG_P5_MIPI_ANA_CLK_CTL ISL7998X_REG(5, 0x32) 302 + #define ISL7998X_REG_P5_PLL_ANA_STATUS ISL7998X_REG(5, 0x33) 303 + #define ISL7998X_REG_P5_PLL_ANA_MISC_CTL ISL7998X_REG(5, 0x34) 304 + #define ISL7998X_REG_P5_MIPI_ANA ISL7998X_REG(5, 0x35) 305 + #define ISL7998X_REG_P5_PLL_ANA ISL7998X_REG(5, 0x36) 306 + #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1 ISL7998X_REG(5, 0x38) 307 + #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2 ISL7998X_REG(5, 0x39) 308 + #define ISL7998X_REG_P5_H_LINE_CNT_1 ISL7998X_REG(5, 0x3a) 309 + #define ISL7998X_REG_P5_H_LINE_CNT_2 ISL7998X_REG(5, 0x3b) 310 + #define ISL7998X_REG_P5_HIST_LINE_CNT_1 ISL7998X_REG(5, 0x3c) 311 + #define ISL7998X_REG_P5_HIST_LINE_CNT_2 ISL7998X_REG(5, 0x3d) 312 + 313 + static const struct reg_sequence isl7998x_init_seq_1[] = { 314 + { ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN, 0xff }, 315 + { ISL7998X_REG_PX_DEC_SDT(0x1), 0x00 }, 316 + { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x1), 0x03 }, 317 + { ISL7998X_REG_PX_DEC_SDT(0x2), 0x00 }, 318 + { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x2), 0x03 }, 319 + { ISL7998X_REG_PX_DEC_SDT(0x3), 0x00 }, 320 + { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x3), 0x03 }, 321 + { ISL7998X_REG_PX_DEC_SDT(0x4), 0x00 }, 322 + { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x4), 0x03 }, 323 + { ISL7998X_REG_P5_LI_ENGINE_CTL, 0x00 }, 324 + { ISL7998X_REG_P0_SW_RESET_CTL, 0x1f, 10 }, 325 + { ISL7998X_REG_P0_IO_BUFFER_CTL, 0x00 }, 326 + { ISL7998X_REG_P0_MPP2_SYNC_CTL, 0xc9 }, 327 + { ISL7998X_REG_P0_IRQ_SYNC_CTL, 0xc9 }, 328 + { ISL7998X_REG_P0_CHAN_1_IRQ, 0x03 }, 329 + { ISL7998X_REG_P0_CHAN_2_IRQ, 0x00 }, 330 + { ISL7998X_REG_P0_CHAN_3_IRQ, 0x00 }, 331 + { ISL7998X_REG_P0_CHAN_4_IRQ, 0x00 }, 332 + { ISL7998X_REG_P5_LI_ENGINE_CTL, 0x02 }, 333 + { ISL7998X_REG_P5_LI_ENGINE_LINE_CTL, 0x85 }, 334 + { ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH, 0xa0 }, 335 + { ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x18 }, 336 + { ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x40 }, 337 + { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x40 }, 338 + { ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 }, 339 + { ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 }, 340 + { ISL7998X_REG_P5_TP_GEN_MIPI, 0x00 }, 341 + { ISL7998X_REG_P5_ESC_MODE_TIME_CTL, 0x0c }, 342 + { ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x00 }, 343 + { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 }, 344 + { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x19 }, 345 + { ISL7998X_REG_P5_PSF_FIELD_END_CTL_1, 0x18 }, 346 + { ISL7998X_REG_P5_PSF_FIELD_END_CTL_2, 0xf1 }, 347 + { ISL7998X_REG_P5_PSF_FIELD_END_CTL_3, 0x00 }, 348 + { ISL7998X_REG_P5_PSF_FIELD_END_CTL_4, 0xf1 }, 349 + { ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1, 0x00 }, 350 + { ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2, 0x00 }, 351 + { ISL7998X_REG_P5_MIPI_ANA_CLK_CTL, 0x00 }, 352 + { ISL7998X_REG_P5_PLL_ANA_STATUS, 0xc0 }, 353 + { ISL7998X_REG_P5_PLL_ANA_MISC_CTL, 0x18 }, 354 + { ISL7998X_REG_P5_PLL_ANA, 0x00 }, 355 + { ISL7998X_REG_P0_SW_RESET_CTL, 0x10, 10 }, 356 + /* Page 0xf means write to all of pages 1,2,3,4 */ 357 + { ISL7998X_REG_PX_DEC_VDELAY_LO(0xf), 0x14 }, 358 + { ISL7998X_REG_PX_DEC_MISC3(0xf), 0xe6 }, 359 + { ISL7998X_REG_PX_DEC_CLMD(0xf), 0x85 }, 360 + { ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(0xf), 0x11 }, 361 + { ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 0x00 }, 362 + { ISL7998X_REG_P0_CLK_CTL_1, 0x1f }, 363 + { ISL7998X_REG_P0_CLK_CTL_2, 0x43 }, 364 + { ISL7998X_REG_P0_CLK_CTL_3, 0x4f }, 365 + }; 366 + 367 + static const struct reg_sequence isl7998x_init_seq_2[] = { 368 + { ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x10 }, 369 + { ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT, 0xe4 }, 370 + { ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x00 }, 371 + { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x60 }, 372 + { ISL7998X_REG_P5_MIPI_READ_START_CTL, 0x2b }, 373 + { ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL, 0x02 }, 374 + { ISL7998X_REG_P5_ONE_FIELD_MODE_CTL, 0x00 }, 375 + { ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR, 0x62 }, 376 + { ISL7998X_REG_P5_TP_GEN_BAR_PATTERN, 0x02 }, 377 + { ISL7998X_REG_P5_MIPI_PCNT_PSFRM, 0x36 }, 378 + { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0x00 }, 379 + { ISL7998X_REG_P5_MIPI_VBLANK_PSFRM, 0x6c }, 380 + { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0x00 }, 381 + { ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 }, 382 + { ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 }, 383 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1, 0x77 }, 384 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2, 0x17 }, 385 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3, 0x08 }, 386 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4, 0x38 }, 387 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5, 0x14 }, 388 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6, 0xf6 }, 389 + { ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1, 0x00 }, 390 + { ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD, 0x17 }, 391 + { ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD, 0x0a }, 392 + { ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2, 0x71 }, 393 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7, 0x7a }, 394 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8, 0x0f }, 395 + { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9, 0x8c }, 396 + { ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x08 }, 397 + { ISL7998X_REG_P5_FIFO_THRSH_CNT_1, 0x01 }, 398 + { ISL7998X_REG_P5_FIFO_THRSH_CNT_2, 0x0e }, 399 + { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 }, 400 + { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x00 }, 401 + { ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 0x03 }, 402 + { ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2, 0xc0 }, 403 + { ISL7998X_REG_P5_H_LINE_CNT_1, 0x06 }, 404 + { ISL7998X_REG_P5_H_LINE_CNT_2, 0xb3 }, 405 + { ISL7998X_REG_P5_HIST_LINE_CNT_1, 0x00 }, 406 + { ISL7998X_REG_P5_HIST_LINE_CNT_2, 0xf1 }, 407 + { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x00 }, 408 + { ISL7998X_REG_P5_MIPI_ANA, 0x00 }, 409 + /* 410 + * Wait a bit after reset so that the chip can capture a frame 411 + * and update internal line counters. 412 + */ 413 + { ISL7998X_REG_P0_SW_RESET_CTL, 0x00, 50 }, 414 + }; 415 + 416 + enum isl7998x_pads { 417 + ISL7998X_PAD_OUT, 418 + ISL7998X_PAD_VIN1, 419 + ISL7998X_PAD_VIN2, 420 + ISL7998X_PAD_VIN3, 421 + ISL7998X_PAD_VIN4, 422 + ISL7998X_NUM_PADS 423 + }; 424 + 425 + struct isl7998x_datafmt { 426 + u32 code; 427 + enum v4l2_colorspace colorspace; 428 + }; 429 + 430 + static const struct isl7998x_datafmt isl7998x_colour_fmts[] = { 431 + { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB }, 432 + }; 433 + 434 + /* Menu items for LINK_FREQ V4L2 control */ 435 + static const s64 link_freq_menu_items[] = { 436 + /* 1 channel, 1 lane or 2 channels, 2 lanes */ 437 + 108000000, 438 + /* 2 channels, 1 lane or 4 channels, 2 lanes */ 439 + 216000000, 440 + /* 4 channels, 1 lane */ 441 + 432000000, 442 + }; 443 + 444 + /* Menu items for TEST_PATTERN V4L2 control */ 445 + static const char * const isl7998x_test_pattern_menu[] = { 446 + "Disabled", 447 + "Enabled", 448 + }; 449 + 450 + static const char * const isl7998x_test_pattern_bars[] = { 451 + "bbbbwb", "bbbwwb", "bbwbwb", "bbwwwb", 452 + }; 453 + 454 + static const char * const isl7998x_test_pattern_colors[] = { 455 + "Yellow", "Blue", "Green", "Pink", 456 + }; 457 + 458 + struct isl7998x_mode { 459 + unsigned int width; 460 + unsigned int height; 461 + enum v4l2_field field; 462 + }; 463 + 464 + static const struct isl7998x_mode supported_modes[] = { 465 + { 466 + .width = 720, 467 + .height = 576, 468 + .field = V4L2_FIELD_SEQ_TB, 469 + }, 470 + { 471 + .width = 720, 472 + .height = 480, 473 + .field = V4L2_FIELD_SEQ_BT, 474 + }, 475 + }; 476 + 477 + static const struct isl7998x_video_std { 478 + const v4l2_std_id norm; 479 + unsigned int id; 480 + const struct isl7998x_mode *mode; 481 + } isl7998x_std_res[] = { 482 + { V4L2_STD_NTSC_443, 483 + ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443, 484 + &supported_modes[1] }, 485 + { V4L2_STD_PAL_M, 486 + ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M, 487 + &supported_modes[1] }, 488 + { V4L2_STD_PAL_Nc, 489 + ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN, 490 + &supported_modes[0] }, 491 + { V4L2_STD_PAL_N, 492 + ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL, 493 + &supported_modes[0] }, 494 + { V4L2_STD_PAL_60, 495 + ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60, 496 + &supported_modes[1] }, 497 + { V4L2_STD_NTSC, 498 + ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M, 499 + &supported_modes[1] }, 500 + { V4L2_STD_PAL, 501 + ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL, 502 + &supported_modes[0] }, 503 + { V4L2_STD_SECAM, 504 + ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM, 505 + &supported_modes[0] }, 506 + { V4L2_STD_UNKNOWN, 507 + ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN, 508 + &supported_modes[1] }, 509 + }; 510 + 511 + struct isl7998x { 512 + struct v4l2_subdev subdev; 513 + struct regmap *regmap; 514 + struct gpio_desc *pd_gpio; 515 + struct gpio_desc *rstb_gpio; 516 + unsigned int nr_mipi_lanes; 517 + u32 nr_inputs; 518 + 519 + const struct isl7998x_datafmt *fmt; 520 + v4l2_std_id norm; 521 + struct media_pad pads[ISL7998X_NUM_PADS]; 522 + 523 + int enabled; 524 + 525 + /* protect fmt, norm, enabled */ 526 + struct mutex lock; 527 + 528 + struct v4l2_ctrl_handler ctrl_handler; 529 + /* protect ctrl_handler */ 530 + struct mutex ctrl_mutex; 531 + 532 + /* V4L2 Controls */ 533 + struct v4l2_ctrl *link_freq; 534 + u8 test_pattern; 535 + u8 test_pattern_bars; 536 + u8 test_pattern_chans; 537 + u8 test_pattern_color; 538 + }; 539 + 540 + static struct isl7998x *sd_to_isl7998x(struct v4l2_subdev *sd) 541 + { 542 + return container_of(sd, struct isl7998x, subdev); 543 + } 544 + 545 + static struct isl7998x *i2c_to_isl7998x(const struct i2c_client *client) 546 + { 547 + return sd_to_isl7998x(i2c_get_clientdata(client)); 548 + } 549 + 550 + static unsigned int isl7998x_norm_to_val(v4l2_std_id norm) 551 + { 552 + unsigned int i; 553 + 554 + for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++) 555 + if (isl7998x_std_res[i].norm & norm) 556 + break; 557 + if (i == ARRAY_SIZE(isl7998x_std_res)) 558 + return ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN; 559 + 560 + return isl7998x_std_res[i].id; 561 + } 562 + 563 + static const struct isl7998x_mode *isl7998x_norm_to_mode(v4l2_std_id norm) 564 + { 565 + unsigned int i; 566 + 567 + for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++) 568 + if (isl7998x_std_res[i].norm & norm) 569 + break; 570 + /* Use NTSC default resolution during standard detection */ 571 + if (i == ARRAY_SIZE(isl7998x_std_res)) 572 + return &supported_modes[1]; 573 + 574 + return isl7998x_std_res[i].mode; 575 + } 576 + 577 + static int isl7998x_get_nr_inputs(struct device_node *of_node) 578 + { 579 + struct device_node *port; 580 + unsigned int inputs = 0; 581 + unsigned int i; 582 + 583 + if (of_graph_get_endpoint_count(of_node) > ISL7998X_NUM_PADS) 584 + return -EINVAL; 585 + 586 + /* 587 + * The driver does not provide means to remap the input ports. It 588 + * always configures input ports to start from VID1. Ensure that the 589 + * device tree is correct. 590 + */ 591 + for (i = ISL7998X_PAD_VIN1; i <= ISL7998X_PAD_VIN4; i++) { 592 + port = of_graph_get_port_by_id(of_node, i); 593 + if (!port) 594 + continue; 595 + 596 + inputs |= BIT(i); 597 + of_node_put(port); 598 + } 599 + 600 + switch (inputs) { 601 + case BIT(ISL7998X_PAD_VIN1): 602 + return 1; 603 + case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2): 604 + return 2; 605 + case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2) | 606 + BIT(ISL7998X_PAD_VIN3) | BIT(ISL7998X_PAD_VIN4): 607 + return 4; 608 + default: 609 + return -EINVAL; 610 + } 611 + } 612 + 613 + static int isl7998x_wait_power_on(struct isl7998x *isl7998x) 614 + { 615 + struct device *dev = isl7998x->subdev.dev; 616 + u32 chip_id; 617 + int ret; 618 + int err; 619 + 620 + ret = read_poll_timeout(regmap_read, err, !err, 2000, 20000, false, 621 + isl7998x->regmap, 622 + ISL7998X_REG_P0_PRODUCT_ID_CODE, &chip_id); 623 + if (ret) { 624 + dev_err(dev, "timeout while waiting for ISL7998X\n"); 625 + return ret; 626 + } 627 + 628 + dev_dbg(dev, "Found ISL799%x\n", chip_id); 629 + 630 + return ret; 631 + } 632 + 633 + static int isl7998x_set_standard(struct isl7998x *isl7998x, v4l2_std_id norm) 634 + { 635 + const struct isl7998x_mode *mode = isl7998x_norm_to_mode(norm); 636 + unsigned int val = isl7998x_norm_to_val(norm); 637 + unsigned int width = mode->width; 638 + unsigned int i; 639 + int ret; 640 + 641 + for (i = 0; i < ISL7998X_INPUTS; i++) { 642 + ret = regmap_write_bits(isl7998x->regmap, 643 + ISL7998X_REG_PX_DEC_SDT(i + 1), 644 + ISL7998X_REG_PX_DEC_SDT_STANDARD, 645 + val); 646 + if (ret) 647 + return ret; 648 + } 649 + 650 + ret = regmap_write(isl7998x->regmap, 651 + ISL7998X_REG_P5_LI_ENGINE_LINE_CTL, 652 + 0x20 | ((width >> 7) & 0x1f)); 653 + if (ret) 654 + return ret; 655 + 656 + ret = regmap_write(isl7998x->regmap, 657 + ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH, 658 + (width << 1) & 0xff); 659 + if (ret) 660 + return ret; 661 + 662 + return 0; 663 + } 664 + 665 + static int isl7998x_init(struct isl7998x *isl7998x) 666 + { 667 + const unsigned int lanes = isl7998x->nr_mipi_lanes; 668 + const u32 isl7998x_video_in_chan_map[] = { 0x00, 0x11, 0x02, 0x02 }; 669 + const struct reg_sequence isl7998x_init_seq_custom[] = { 670 + { ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL, 671 + isl7998x_video_in_chan_map[isl7998x->nr_inputs - 1] }, 672 + { ISL7998X_REG_P0_CLK_CTL_4, 673 + (lanes == 1) ? 0x40 : 0x41 }, 674 + { ISL7998X_REG_P5_LI_ENGINE_CTL, 675 + (lanes == 1) ? 0x01 : 0x02 }, 676 + }; 677 + struct device *dev = isl7998x->subdev.dev; 678 + struct regmap *regmap = isl7998x->regmap; 679 + int ret; 680 + 681 + dev_dbg(dev, "configuring %d lanes for %d inputs (norm %s)\n", 682 + isl7998x->nr_mipi_lanes, isl7998x->nr_inputs, 683 + v4l2_norm_to_name(isl7998x->norm)); 684 + 685 + ret = regmap_register_patch(regmap, isl7998x_init_seq_1, 686 + ARRAY_SIZE(isl7998x_init_seq_1)); 687 + if (ret) 688 + return ret; 689 + 690 + mutex_lock(&isl7998x->lock); 691 + ret = isl7998x_set_standard(isl7998x, isl7998x->norm); 692 + mutex_unlock(&isl7998x->lock); 693 + if (ret) 694 + return ret; 695 + 696 + ret = regmap_register_patch(regmap, isl7998x_init_seq_custom, 697 + ARRAY_SIZE(isl7998x_init_seq_custom)); 698 + if (ret) 699 + return ret; 700 + 701 + return regmap_register_patch(regmap, isl7998x_init_seq_2, 702 + ARRAY_SIZE(isl7998x_init_seq_2)); 703 + } 704 + 705 + static int isl7998x_set_test_pattern(struct isl7998x *isl7998x) 706 + { 707 + const struct reg_sequence isl7998x_init_seq_tpg_off[] = { 708 + { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0 }, 709 + { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0 } 710 + }; 711 + const struct reg_sequence isl7998x_init_seq_tpg_on[] = { 712 + { ISL7998X_REG_P5_TP_GEN_BAR_PATTERN, 713 + isl7998x->test_pattern_bars << 6 }, 714 + { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 715 + isl7998x->norm & V4L2_STD_PAL ? BIT(2) : 0 }, 716 + { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 717 + (isl7998x->test_pattern_chans << 4) | 718 + (isl7998x->test_pattern_color << 2) } 719 + }; 720 + struct device *dev = isl7998x->subdev.dev; 721 + struct regmap *regmap = isl7998x->regmap; 722 + int ret; 723 + 724 + if (pm_runtime_get_if_in_use(dev) <= 0) 725 + return 0; 726 + 727 + if (isl7998x->test_pattern != 0) { 728 + dev_dbg(dev, "enabling test pattern: channels 0x%x, %s, %s\n", 729 + isl7998x->test_pattern_chans, 730 + isl7998x_test_pattern_bars[isl7998x->test_pattern_bars], 731 + isl7998x_test_pattern_colors[isl7998x->test_pattern_color]); 732 + ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_on, 733 + ARRAY_SIZE(isl7998x_init_seq_tpg_on)); 734 + } else { 735 + ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_off, 736 + ARRAY_SIZE(isl7998x_init_seq_tpg_off)); 737 + } 738 + 739 + pm_runtime_put(dev); 740 + 741 + return ret; 742 + } 743 + 744 + #ifdef CONFIG_VIDEO_ADV_DEBUG 745 + static int isl7998x_g_register(struct v4l2_subdev *sd, 746 + struct v4l2_dbg_register *reg) 747 + { 748 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 749 + int ret; 750 + u32 val; 751 + 752 + ret = regmap_read(isl7998x->regmap, reg->reg, &val); 753 + if (ret) 754 + return ret; 755 + 756 + reg->size = 1; 757 + reg->val = val; 758 + 759 + return 0; 760 + } 761 + 762 + static int isl7998x_s_register(struct v4l2_subdev *sd, 763 + const struct v4l2_dbg_register *reg) 764 + { 765 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 766 + 767 + return regmap_write(isl7998x->regmap, reg->reg, reg->val); 768 + } 769 + #endif 770 + 771 + static int isl7998x_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm) 772 + { 773 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 774 + 775 + mutex_lock(&isl7998x->lock); 776 + *norm = isl7998x->norm; 777 + mutex_unlock(&isl7998x->lock); 778 + 779 + return 0; 780 + } 781 + 782 + static int isl7998x_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 783 + { 784 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 785 + struct i2c_client *client = v4l2_get_subdevdata(sd); 786 + struct device *dev = &client->dev; 787 + int ret = 0; 788 + 789 + mutex_lock(&isl7998x->lock); 790 + if (isl7998x->enabled) { 791 + ret = -EBUSY; 792 + mutex_unlock(&isl7998x->lock); 793 + return ret; 794 + } 795 + isl7998x->norm = norm; 796 + mutex_unlock(&isl7998x->lock); 797 + 798 + if (pm_runtime_get_if_in_use(dev) <= 0) 799 + return ret; 800 + 801 + ret = isl7998x_set_standard(isl7998x, norm); 802 + 803 + pm_runtime_put(dev); 804 + 805 + return ret; 806 + } 807 + 808 + static int isl7998x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 809 + { 810 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 811 + struct i2c_client *client = v4l2_get_subdevdata(sd); 812 + struct device *dev = &client->dev; 813 + unsigned int std_id[ISL7998X_INPUTS]; 814 + unsigned int i; 815 + int ret; 816 + u32 reg; 817 + 818 + ret = pm_runtime_resume_and_get(dev); 819 + if (ret) 820 + return ret; 821 + 822 + dev_dbg(dev, "starting video standard detection\n"); 823 + 824 + mutex_lock(&isl7998x->lock); 825 + if (isl7998x->enabled) { 826 + ret = -EBUSY; 827 + goto out_unlock; 828 + } 829 + 830 + ret = isl7998x_set_standard(isl7998x, V4L2_STD_UNKNOWN); 831 + if (ret) 832 + goto out_unlock; 833 + 834 + for (i = 0; i < ISL7998X_INPUTS; i++) { 835 + ret = regmap_write(isl7998x->regmap, 836 + ISL7998X_REG_PX_DEC_SDTR(i + 1), 837 + ISL7998X_REG_PX_DEC_SDTR_ATSTART); 838 + if (ret) 839 + goto out_reset_std; 840 + } 841 + 842 + for (i = 0; i < ISL7998X_INPUTS; i++) { 843 + ret = regmap_read_poll_timeout(isl7998x->regmap, 844 + ISL7998X_REG_PX_DEC_SDT(i + 1), 845 + reg, 846 + !(reg & ISL7998X_REG_PX_DEC_SDT_DET), 847 + 2000, 500 * USEC_PER_MSEC); 848 + if (ret) 849 + goto out_reset_std; 850 + std_id[i] = FIELD_GET(ISL7998X_REG_PX_DEC_SDT_NOW, reg); 851 + } 852 + 853 + /* 854 + * According to Renesas FAE, all input cameras must have the 855 + * same standard on this chip. 856 + */ 857 + for (i = 0; i < isl7998x->nr_inputs; i++) { 858 + dev_dbg(dev, "input %d: detected %s\n", 859 + i, v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm)); 860 + if (std_id[0] != std_id[i]) 861 + dev_warn(dev, 862 + "incompatible standards: %s on input %d (expected %s)\n", 863 + v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm), i, 864 + v4l2_norm_to_name(isl7998x_std_res[std_id[0]].norm)); 865 + } 866 + 867 + *std = isl7998x_std_res[std_id[0]].norm; 868 + 869 + out_reset_std: 870 + isl7998x_set_standard(isl7998x, isl7998x->norm); 871 + out_unlock: 872 + mutex_unlock(&isl7998x->lock); 873 + pm_runtime_put(dev); 874 + 875 + return ret; 876 + } 877 + 878 + static int isl7998x_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std) 879 + { 880 + *std = V4L2_STD_ALL; 881 + 882 + return 0; 883 + } 884 + 885 + static int isl7998x_g_input_status(struct v4l2_subdev *sd, u32 *status) 886 + { 887 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 888 + struct i2c_client *client = v4l2_get_subdevdata(sd); 889 + struct device *dev = &client->dev; 890 + unsigned int i; 891 + int ret = 0; 892 + u32 reg; 893 + 894 + if (!pm_runtime_active(dev)) { 895 + *status |= V4L2_IN_ST_NO_POWER; 896 + return 0; 897 + } 898 + 899 + for (i = 0; i < isl7998x->nr_inputs; i++) { 900 + ret = regmap_read(isl7998x->regmap, 901 + ISL7998X_REG_PX_DEC_STATUS_1(i + 1), &reg); 902 + if (!ret) { 903 + if (reg & ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS) 904 + *status |= V4L2_IN_ST_NO_SIGNAL; 905 + if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_HLOCK)) 906 + *status |= V4L2_IN_ST_NO_H_LOCK; 907 + if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_VLOCK)) 908 + *status |= V4L2_IN_ST_NO_V_LOCK; 909 + } 910 + } 911 + 912 + return ret; 913 + } 914 + 915 + static int isl7998x_s_stream(struct v4l2_subdev *sd, int enable) 916 + { 917 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 918 + struct i2c_client *client = v4l2_get_subdevdata(sd); 919 + struct device *dev = &client->dev; 920 + int ret = 0; 921 + u32 reg; 922 + 923 + dev_dbg(dev, "stream %s\n", enable ? "ON" : "OFF"); 924 + 925 + mutex_lock(&isl7998x->lock); 926 + if (isl7998x->enabled == enable) 927 + goto out; 928 + isl7998x->enabled = enable; 929 + 930 + if (enable) { 931 + ret = isl7998x_set_test_pattern(isl7998x); 932 + if (ret) 933 + goto out; 934 + } 935 + 936 + regmap_read(isl7998x->regmap, 937 + ISL7998X_REG_P5_LI_ENGINE_CTL, &reg); 938 + if (enable) 939 + reg &= ~BIT(7); 940 + else 941 + reg |= BIT(7); 942 + ret = regmap_write(isl7998x->regmap, 943 + ISL7998X_REG_P5_LI_ENGINE_CTL, reg); 944 + 945 + out: 946 + mutex_unlock(&isl7998x->lock); 947 + 948 + return ret; 949 + } 950 + 951 + static int isl7998x_pre_streamon(struct v4l2_subdev *sd, u32 flags) 952 + { 953 + struct i2c_client *client = v4l2_get_subdevdata(sd); 954 + struct device *dev = &client->dev; 955 + 956 + return pm_runtime_resume_and_get(dev); 957 + } 958 + 959 + static int isl7998x_post_streamoff(struct v4l2_subdev *sd) 960 + { 961 + struct i2c_client *client = v4l2_get_subdevdata(sd); 962 + struct device *dev = &client->dev; 963 + 964 + pm_runtime_put(dev); 965 + 966 + return 0; 967 + } 968 + 969 + static int isl7998x_enum_mbus_code(struct v4l2_subdev *sd, 970 + struct v4l2_subdev_state *sd_state, 971 + struct v4l2_subdev_mbus_code_enum *code) 972 + { 973 + if (code->index >= ARRAY_SIZE(isl7998x_colour_fmts)) 974 + return -EINVAL; 975 + 976 + code->code = isl7998x_colour_fmts[code->index].code; 977 + 978 + return 0; 979 + } 980 + 981 + static int isl7998x_enum_frame_size(struct v4l2_subdev *sd, 982 + struct v4l2_subdev_state *sd_state, 983 + struct v4l2_subdev_frame_size_enum *fse) 984 + { 985 + if (fse->index >= ARRAY_SIZE(supported_modes)) 986 + return -EINVAL; 987 + 988 + if (fse->code != isl7998x_colour_fmts[0].code) 989 + return -EINVAL; 990 + 991 + fse->min_width = supported_modes[fse->index].width; 992 + fse->max_width = fse->min_width; 993 + fse->min_height = supported_modes[fse->index].height; 994 + fse->max_height = fse->min_height; 995 + 996 + return 0; 997 + } 998 + 999 + static int isl7998x_get_fmt(struct v4l2_subdev *sd, 1000 + struct v4l2_subdev_state *sd_state, 1001 + struct v4l2_subdev_format *format) 1002 + { 1003 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 1004 + struct v4l2_mbus_framefmt *mf = &format->format; 1005 + const struct isl7998x_mode *mode; 1006 + 1007 + mutex_lock(&isl7998x->lock); 1008 + 1009 + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 1010 + format->format = *v4l2_subdev_get_try_format(sd, sd_state, 1011 + format->pad); 1012 + goto out; 1013 + } 1014 + 1015 + mode = isl7998x_norm_to_mode(isl7998x->norm); 1016 + 1017 + mf->width = mode->width; 1018 + mf->height = mode->height; 1019 + mf->code = isl7998x->fmt->code; 1020 + mf->field = mode->field; 1021 + mf->colorspace = 0; 1022 + 1023 + out: 1024 + mutex_unlock(&isl7998x->lock); 1025 + 1026 + return 0; 1027 + } 1028 + 1029 + static int isl7998x_set_fmt(struct v4l2_subdev *sd, 1030 + struct v4l2_subdev_state *sd_state, 1031 + struct v4l2_subdev_format *format) 1032 + { 1033 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 1034 + struct v4l2_mbus_framefmt *mf = &format->format; 1035 + const struct isl7998x_mode *mode; 1036 + 1037 + mutex_lock(&isl7998x->lock); 1038 + 1039 + mode = isl7998x_norm_to_mode(isl7998x->norm); 1040 + 1041 + mf->width = mode->width; 1042 + mf->height = mode->height; 1043 + mf->code = isl7998x->fmt->code; 1044 + mf->field = mode->field; 1045 + 1046 + if (format->which == V4L2_SUBDEV_FORMAT_TRY) 1047 + *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format; 1048 + 1049 + mutex_unlock(&isl7998x->lock); 1050 + 1051 + return 0; 1052 + } 1053 + 1054 + static int isl7998x_set_ctrl(struct v4l2_ctrl *ctrl) 1055 + { 1056 + struct isl7998x *isl7998x = container_of(ctrl->handler, 1057 + struct isl7998x, ctrl_handler); 1058 + int ret = 0; 1059 + 1060 + switch (ctrl->id) { 1061 + case V4L2_CID_TEST_PATTERN_BARS: 1062 + mutex_lock(&isl7998x->lock); 1063 + isl7998x->test_pattern_bars = ctrl->val & 0x3; 1064 + ret = isl7998x_set_test_pattern(isl7998x); 1065 + mutex_unlock(&isl7998x->lock); 1066 + break; 1067 + case V4L2_CID_TEST_PATTERN_CHANNELS: 1068 + mutex_lock(&isl7998x->lock); 1069 + isl7998x->test_pattern_chans = ctrl->val & 0xf; 1070 + ret = isl7998x_set_test_pattern(isl7998x); 1071 + mutex_unlock(&isl7998x->lock); 1072 + break; 1073 + case V4L2_CID_TEST_PATTERN_COLOR: 1074 + mutex_lock(&isl7998x->lock); 1075 + isl7998x->test_pattern_color = ctrl->val & 0x3; 1076 + ret = isl7998x_set_test_pattern(isl7998x); 1077 + mutex_unlock(&isl7998x->lock); 1078 + break; 1079 + case V4L2_CID_TEST_PATTERN: 1080 + mutex_lock(&isl7998x->lock); 1081 + isl7998x->test_pattern = ctrl->val; 1082 + ret = isl7998x_set_test_pattern(isl7998x); 1083 + mutex_unlock(&isl7998x->lock); 1084 + break; 1085 + } 1086 + 1087 + return ret; 1088 + } 1089 + 1090 + static const struct v4l2_subdev_core_ops isl7998x_subdev_core_ops = { 1091 + #ifdef CONFIG_VIDEO_ADV_DEBUG 1092 + .g_register = isl7998x_g_register, 1093 + .s_register = isl7998x_s_register, 1094 + #endif 1095 + }; 1096 + 1097 + static const struct v4l2_subdev_video_ops isl7998x_subdev_video_ops = { 1098 + .g_std = isl7998x_g_std, 1099 + .s_std = isl7998x_s_std, 1100 + .querystd = isl7998x_querystd, 1101 + .g_tvnorms = isl7998x_g_tvnorms, 1102 + .g_input_status = isl7998x_g_input_status, 1103 + .s_stream = isl7998x_s_stream, 1104 + .pre_streamon = isl7998x_pre_streamon, 1105 + .post_streamoff = isl7998x_post_streamoff, 1106 + }; 1107 + 1108 + static const struct v4l2_subdev_pad_ops isl7998x_subdev_pad_ops = { 1109 + .enum_mbus_code = isl7998x_enum_mbus_code, 1110 + .enum_frame_size = isl7998x_enum_frame_size, 1111 + .get_fmt = isl7998x_get_fmt, 1112 + .set_fmt = isl7998x_set_fmt, 1113 + }; 1114 + 1115 + static const struct v4l2_subdev_ops isl7998x_subdev_ops = { 1116 + .core = &isl7998x_subdev_core_ops, 1117 + .video = &isl7998x_subdev_video_ops, 1118 + .pad = &isl7998x_subdev_pad_ops, 1119 + }; 1120 + 1121 + static const struct media_entity_operations isl7998x_entity_ops = { 1122 + .link_validate = v4l2_subdev_link_validate, 1123 + }; 1124 + 1125 + static const struct v4l2_ctrl_ops isl7998x_ctrl_ops = { 1126 + .s_ctrl = isl7998x_set_ctrl, 1127 + }; 1128 + 1129 + static const struct v4l2_ctrl_config isl7998x_ctrls[] = { 1130 + { 1131 + .ops = &isl7998x_ctrl_ops, 1132 + .id = V4L2_CID_TEST_PATTERN_BARS, 1133 + .type = V4L2_CTRL_TYPE_MENU, 1134 + .name = "Test Pattern Bars", 1135 + .max = ARRAY_SIZE(isl7998x_test_pattern_bars) - 1, 1136 + .def = 0, 1137 + .qmenu = isl7998x_test_pattern_bars, 1138 + }, { 1139 + .ops = &isl7998x_ctrl_ops, 1140 + .id = V4L2_CID_TEST_PATTERN_CHANNELS, 1141 + .type = V4L2_CTRL_TYPE_INTEGER, 1142 + .name = "Test Pattern Channels", 1143 + .min = 0, 1144 + .max = 0xf, 1145 + .step = 1, 1146 + .def = 0xf, 1147 + .flags = 0, 1148 + }, { 1149 + .ops = &isl7998x_ctrl_ops, 1150 + .id = V4L2_CID_TEST_PATTERN_COLOR, 1151 + .type = V4L2_CTRL_TYPE_MENU, 1152 + .name = "Test Pattern Color", 1153 + .max = ARRAY_SIZE(isl7998x_test_pattern_colors) - 1, 1154 + .def = 0, 1155 + .qmenu = isl7998x_test_pattern_colors, 1156 + }, 1157 + }; 1158 + 1159 + #define ISL7998X_REG_DECODER_ACA_READABLE_RANGE(page) \ 1160 + /* Decoder range */ \ 1161 + regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page), \ 1162 + ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)), \ 1163 + regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page), \ 1164 + ISL7998X_REG_PX_DEC_CSC_CTL(page)), \ 1165 + regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page), \ 1166 + ISL7998X_REG_PX_DEC_HUE(page)), \ 1167 + regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page), \ 1168 + ISL7998X_REG_PX_DEC_CORING(page)), \ 1169 + regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 1170 + ISL7998X_REG_PX_DEC_SDTR(page)), \ 1171 + regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page), \ 1172 + ISL7998X_REG_PX_DEC_DATA_CONV(page)), \ 1173 + regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page), \ 1174 + ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)), \ 1175 + regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page), \ 1176 + ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)), \ 1177 + /* ACA range */ \ 1178 + regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page), \ 1179 + ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)), \ 1180 + regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page), \ 1181 + ISL7998X_REG_PX_ACA_CTL_4(page)), \ 1182 + regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page), \ 1183 + ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)), \ 1184 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page), \ 1185 + ISL7998X_REG_PX_DEC_PAGE(page)) 1186 + 1187 + #define ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(page) \ 1188 + /* Decoder range */ \ 1189 + regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page), \ 1190 + ISL7998X_REG_PX_DEC_INPUT_FMT(page)), \ 1191 + regmap_reg_range(ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page), \ 1192 + ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)), \ 1193 + regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page), \ 1194 + ISL7998X_REG_PX_DEC_CSC_CTL(page)), \ 1195 + regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page), \ 1196 + ISL7998X_REG_PX_DEC_HUE(page)), \ 1197 + regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page), \ 1198 + ISL7998X_REG_PX_DEC_CORING(page)), \ 1199 + regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 1200 + ISL7998X_REG_PX_DEC_SDTR(page)), \ 1201 + regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page), \ 1202 + ISL7998X_REG_PX_DEC_MISC3(page)), \ 1203 + regmap_reg_range(ISL7998X_REG_PX_DEC_CLMD(page), \ 1204 + ISL7998X_REG_PX_DEC_DATA_CONV(page)), \ 1205 + regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page), \ 1206 + ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)), \ 1207 + regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page), \ 1208 + ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)), \ 1209 + /* ACA range */ \ 1210 + regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page), \ 1211 + ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)), \ 1212 + regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_2(page), \ 1213 + ISL7998X_REG_PX_ACA_CTL_4(page)), \ 1214 + regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page), \ 1215 + ISL7998X_REG_PX_ACA_HIST_DATA_LO(page)), \ 1216 + regmap_reg_range(ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page), \ 1217 + ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)), \ 1218 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page), \ 1219 + ISL7998X_REG_PX_DEC_PAGE(page)) 1220 + 1221 + #define ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(page) \ 1222 + /* Decoder range */ \ 1223 + regmap_reg_range(ISL7998X_REG_PX_DEC_STATUS_1(page), \ 1224 + ISL7998X_REG_PX_DEC_STATUS_1(page)), \ 1225 + regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 1226 + ISL7998X_REG_PX_DEC_SDT(page)), \ 1227 + regmap_reg_range(ISL7998X_REG_PX_DEC_MVSN(page), \ 1228 + ISL7998X_REG_PX_DEC_HFREF(page)), \ 1229 + /* ACA range */ \ 1230 + regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page), \ 1231 + ISL7998X_REG_PX_ACA_Y_HIGH(page)), \ 1232 + regmap_reg_range(ISL7998X_REG_PX_ACA_HIST_DATA_LO(page), \ 1233 + ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(page)) 1234 + 1235 + static const struct regmap_range isl7998x_readable_ranges[] = { 1236 + regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE, 1237 + ISL7998X_REG_P0_IRQ_SYNC_CTL), 1238 + regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS, 1239 + ISL7998X_REG_P0_CLOCK_DELAY), 1240 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0), 1241 + ISL7998X_REG_PX_DEC_PAGE(0)), 1242 + 1243 + ISL7998X_REG_DECODER_ACA_READABLE_RANGE(1), 1244 + ISL7998X_REG_DECODER_ACA_READABLE_RANGE(2), 1245 + ISL7998X_REG_DECODER_ACA_READABLE_RANGE(3), 1246 + ISL7998X_REG_DECODER_ACA_READABLE_RANGE(4), 1247 + 1248 + regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL, 1249 + ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL), 1250 + regmap_reg_range(ISL7998X_REG_P5_FIFO_THRSH_CNT_1, 1251 + ISL7998X_REG_P5_PLL_ANA), 1252 + regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 1253 + ISL7998X_REG_P5_HIST_LINE_CNT_2), 1254 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5), 1255 + ISL7998X_REG_PX_DEC_PAGE(5)), 1256 + }; 1257 + 1258 + static const struct regmap_range isl7998x_writeable_ranges[] = { 1259 + regmap_reg_range(ISL7998X_REG_P0_SW_RESET_CTL, 1260 + ISL7998X_REG_P0_IRQ_SYNC_CTL), 1261 + regmap_reg_range(ISL7998X_REG_P0_CHAN_1_IRQ, 1262 + ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN), 1263 + regmap_reg_range(ISL7998X_REG_P0_CLOCK_DELAY, 1264 + ISL7998X_REG_P0_CLOCK_DELAY), 1265 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0), 1266 + ISL7998X_REG_PX_DEC_PAGE(0)), 1267 + 1268 + ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(1), 1269 + ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(2), 1270 + ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(3), 1271 + ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(4), 1272 + 1273 + regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL, 1274 + ISL7998X_REG_P5_ESC_MODE_TIME_CTL), 1275 + regmap_reg_range(ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 1276 + ISL7998X_REG_P5_PLL_ANA), 1277 + regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 1278 + ISL7998X_REG_P5_HIST_LINE_CNT_2), 1279 + regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5), 1280 + ISL7998X_REG_PX_DEC_PAGE(5)), 1281 + 1282 + ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(0xf), 1283 + }; 1284 + 1285 + static const struct regmap_range isl7998x_volatile_ranges[] = { 1286 + /* Product id code register is used to check availability */ 1287 + regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE, 1288 + ISL7998X_REG_P0_PRODUCT_ID_CODE), 1289 + regmap_reg_range(ISL7998X_REG_P0_MPP1_SYNC_CTL, 1290 + ISL7998X_REG_P0_IRQ_SYNC_CTL), 1291 + regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS, 1292 + ISL7998X_REG_P0_INTERRUPT_STATUS), 1293 + regmap_reg_range(ISL7998X_REG_P0_CHAN_1_STATUS, 1294 + ISL7998X_REG_P0_SHORT_DIAG_STATUS), 1295 + 1296 + ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(1), 1297 + ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(2), 1298 + ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(3), 1299 + ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(4), 1300 + 1301 + regmap_reg_range(ISL7998X_REG_P5_AUTO_TEST_ERR_DET, 1302 + ISL7998X_REG_P5_PIC_HEIGHT_LOW), 1303 + }; 1304 + 1305 + static const struct regmap_access_table isl7998x_readable_table = { 1306 + .yes_ranges = isl7998x_readable_ranges, 1307 + .n_yes_ranges = ARRAY_SIZE(isl7998x_readable_ranges), 1308 + }; 1309 + 1310 + static const struct regmap_access_table isl7998x_writeable_table = { 1311 + .yes_ranges = isl7998x_writeable_ranges, 1312 + .n_yes_ranges = ARRAY_SIZE(isl7998x_writeable_ranges), 1313 + }; 1314 + 1315 + static const struct regmap_access_table isl7998x_volatile_table = { 1316 + .yes_ranges = isl7998x_volatile_ranges, 1317 + .n_yes_ranges = ARRAY_SIZE(isl7998x_volatile_ranges), 1318 + }; 1319 + 1320 + static const struct regmap_range_cfg isl7998x_ranges[] = { 1321 + { 1322 + .range_min = ISL7998X_REG_PN_BASE(0), 1323 + .range_max = ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 1324 + .selector_reg = ISL7998X_REG_PX_DEC_PAGE(0), 1325 + .selector_mask = ISL7998X_REG_PX_DEC_PAGE_MASK, 1326 + .window_start = 0, 1327 + .window_len = 256, 1328 + } 1329 + }; 1330 + 1331 + static const struct regmap_config isl7998x_regmap = { 1332 + .reg_bits = 8, 1333 + .val_bits = 8, 1334 + .max_register = ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 1335 + .ranges = isl7998x_ranges, 1336 + .num_ranges = ARRAY_SIZE(isl7998x_ranges), 1337 + .rd_table = &isl7998x_readable_table, 1338 + .wr_table = &isl7998x_writeable_table, 1339 + .volatile_table = &isl7998x_volatile_table, 1340 + .cache_type = REGCACHE_RBTREE, 1341 + }; 1342 + 1343 + static int isl7998x_mc_init(struct isl7998x *isl7998x) 1344 + { 1345 + unsigned int i; 1346 + 1347 + isl7998x->subdev.entity.ops = &isl7998x_entity_ops; 1348 + isl7998x->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 1349 + 1350 + isl7998x->pads[ISL7998X_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; 1351 + for (i = ISL7998X_PAD_VIN1; i < ISL7998X_NUM_PADS; i++) 1352 + isl7998x->pads[i].flags = MEDIA_PAD_FL_SINK; 1353 + 1354 + return media_entity_pads_init(&isl7998x->subdev.entity, 1355 + ISL7998X_NUM_PADS, 1356 + isl7998x->pads); 1357 + } 1358 + 1359 + static int get_link_freq_menu_index(unsigned int lanes, 1360 + unsigned int inputs) 1361 + { 1362 + int ret = -EINVAL; 1363 + 1364 + switch (lanes) { 1365 + case 1: 1366 + if (inputs == 1) 1367 + ret = 0; 1368 + if (inputs == 2) 1369 + ret = 1; 1370 + if (inputs == 4) 1371 + ret = 2; 1372 + break; 1373 + case 2: 1374 + if (inputs == 2) 1375 + ret = 0; 1376 + if (inputs == 4) 1377 + ret = 1; 1378 + break; 1379 + default: 1380 + break; 1381 + } 1382 + 1383 + return ret; 1384 + } 1385 + 1386 + static void isl7998x_remove_controls(struct isl7998x *isl7998x) 1387 + { 1388 + v4l2_ctrl_handler_free(&isl7998x->ctrl_handler); 1389 + mutex_destroy(&isl7998x->ctrl_mutex); 1390 + } 1391 + 1392 + static int isl7998x_init_controls(struct isl7998x *isl7998x) 1393 + { 1394 + struct v4l2_subdev *sd = &isl7998x->subdev; 1395 + int link_freq_index; 1396 + unsigned int i; 1397 + int ret; 1398 + 1399 + ret = v4l2_ctrl_handler_init(&isl7998x->ctrl_handler, 1400 + 2 + ARRAY_SIZE(isl7998x_ctrls)); 1401 + if (ret) 1402 + return ret; 1403 + 1404 + mutex_init(&isl7998x->ctrl_mutex); 1405 + isl7998x->ctrl_handler.lock = &isl7998x->ctrl_mutex; 1406 + link_freq_index = get_link_freq_menu_index(isl7998x->nr_mipi_lanes, 1407 + isl7998x->nr_inputs); 1408 + if (link_freq_index < 0 || 1409 + link_freq_index >= ARRAY_SIZE(link_freq_menu_items)) { 1410 + dev_err(sd->dev, 1411 + "failed to find MIPI link freq: %d lanes, %d inputs\n", 1412 + isl7998x->nr_mipi_lanes, isl7998x->nr_inputs); 1413 + ret = -EINVAL; 1414 + goto err; 1415 + } 1416 + 1417 + isl7998x->link_freq = v4l2_ctrl_new_int_menu(&isl7998x->ctrl_handler, 1418 + &isl7998x_ctrl_ops, 1419 + V4L2_CID_LINK_FREQ, 1420 + ARRAY_SIZE(link_freq_menu_items) - 1, 1421 + link_freq_index, 1422 + link_freq_menu_items); 1423 + if (isl7998x->link_freq) 1424 + isl7998x->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 1425 + 1426 + for (i = 0; i < ARRAY_SIZE(isl7998x_ctrls); i++) 1427 + v4l2_ctrl_new_custom(&isl7998x->ctrl_handler, 1428 + &isl7998x_ctrls[i], NULL); 1429 + 1430 + v4l2_ctrl_new_std_menu_items(&isl7998x->ctrl_handler, 1431 + &isl7998x_ctrl_ops, 1432 + V4L2_CID_TEST_PATTERN, 1433 + ARRAY_SIZE(isl7998x_test_pattern_menu) - 1, 1434 + 0, 0, isl7998x_test_pattern_menu); 1435 + 1436 + ret = isl7998x->ctrl_handler.error; 1437 + if (ret) 1438 + goto err; 1439 + 1440 + isl7998x->subdev.ctrl_handler = &isl7998x->ctrl_handler; 1441 + v4l2_ctrl_handler_setup(&isl7998x->ctrl_handler); 1442 + 1443 + return 0; 1444 + 1445 + err: 1446 + isl7998x_remove_controls(isl7998x); 1447 + 1448 + return ret; 1449 + } 1450 + 1451 + static int isl7998x_probe(struct i2c_client *client) 1452 + { 1453 + struct device *dev = &client->dev; 1454 + struct v4l2_fwnode_endpoint endpoint = { 1455 + .bus_type = V4L2_MBUS_CSI2_DPHY, 1456 + }; 1457 + struct fwnode_handle *ep; 1458 + struct isl7998x *isl7998x; 1459 + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1460 + int nr_inputs; 1461 + int ret; 1462 + 1463 + ret = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA); 1464 + if (!ret) { 1465 + dev_warn(&adapter->dev, 1466 + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); 1467 + return -EIO; 1468 + } 1469 + 1470 + isl7998x = devm_kzalloc(dev, sizeof(*isl7998x), GFP_KERNEL); 1471 + if (!isl7998x) 1472 + return -ENOMEM; 1473 + 1474 + isl7998x->pd_gpio = devm_gpiod_get_optional(dev, "powerdown", 1475 + GPIOD_OUT_HIGH); 1476 + if (IS_ERR(isl7998x->pd_gpio)) 1477 + return dev_err_probe(dev, PTR_ERR(isl7998x->pd_gpio), 1478 + "Failed to retrieve/request PD GPIO\n"); 1479 + 1480 + isl7998x->rstb_gpio = devm_gpiod_get_optional(dev, "reset", 1481 + GPIOD_OUT_HIGH); 1482 + if (IS_ERR(isl7998x->rstb_gpio)) 1483 + return dev_err_probe(dev, PTR_ERR(isl7998x->rstb_gpio), 1484 + "Failed to retrieve/request RSTB GPIO\n"); 1485 + 1486 + isl7998x->regmap = devm_regmap_init_i2c(client, &isl7998x_regmap); 1487 + if (IS_ERR(isl7998x->regmap)) 1488 + return dev_err_probe(dev, PTR_ERR(isl7998x->regmap), 1489 + "Failed to allocate register map\n"); 1490 + 1491 + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 1492 + ISL7998X_PAD_OUT, 0, 0); 1493 + if (!ep) 1494 + return dev_err_probe(dev, -EINVAL, "Missing endpoint node\n"); 1495 + 1496 + ret = v4l2_fwnode_endpoint_parse(ep, &endpoint); 1497 + fwnode_handle_put(ep); 1498 + if (ret) 1499 + return dev_err_probe(dev, ret, "Failed to parse endpoint\n"); 1500 + 1501 + if (endpoint.bus.mipi_csi2.num_data_lanes == 0 || 1502 + endpoint.bus.mipi_csi2.num_data_lanes > 2) 1503 + return dev_err_probe(dev, -EINVAL, 1504 + "Invalid number of MIPI lanes\n"); 1505 + 1506 + isl7998x->nr_mipi_lanes = endpoint.bus.mipi_csi2.num_data_lanes; 1507 + 1508 + nr_inputs = isl7998x_get_nr_inputs(dev->of_node); 1509 + if (nr_inputs < 0) 1510 + return dev_err_probe(dev, nr_inputs, 1511 + "Invalid number of input ports\n"); 1512 + isl7998x->nr_inputs = nr_inputs; 1513 + 1514 + v4l2_i2c_subdev_init(&isl7998x->subdev, client, &isl7998x_subdev_ops); 1515 + isl7998x->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1516 + 1517 + ret = isl7998x_mc_init(isl7998x); 1518 + if (ret < 0) 1519 + return ret; 1520 + 1521 + isl7998x->fmt = &isl7998x_colour_fmts[0]; 1522 + isl7998x->norm = V4L2_STD_NTSC; 1523 + isl7998x->enabled = 0; 1524 + 1525 + mutex_init(&isl7998x->lock); 1526 + 1527 + ret = isl7998x_init_controls(isl7998x); 1528 + if (ret) 1529 + goto err_entity_cleanup; 1530 + 1531 + ret = v4l2_async_register_subdev(&isl7998x->subdev); 1532 + if (ret < 0) 1533 + goto err_controls_cleanup; 1534 + 1535 + pm_runtime_enable(dev); 1536 + 1537 + return 0; 1538 + 1539 + err_controls_cleanup: 1540 + isl7998x_remove_controls(isl7998x); 1541 + err_entity_cleanup: 1542 + media_entity_cleanup(&isl7998x->subdev.entity); 1543 + 1544 + return ret; 1545 + } 1546 + 1547 + static int isl7998x_remove(struct i2c_client *client) 1548 + { 1549 + struct isl7998x *isl7998x = i2c_to_isl7998x(client); 1550 + 1551 + pm_runtime_disable(&client->dev); 1552 + v4l2_async_unregister_subdev(&isl7998x->subdev); 1553 + isl7998x_remove_controls(isl7998x); 1554 + media_entity_cleanup(&isl7998x->subdev.entity); 1555 + 1556 + return 0; 1557 + } 1558 + 1559 + static const struct of_device_id isl7998x_of_match[] = { 1560 + { .compatible = "isil,isl79987", }, 1561 + { /* sentinel */ }, 1562 + }; 1563 + MODULE_DEVICE_TABLE(of, isl7998x_of_match); 1564 + 1565 + static const struct i2c_device_id isl7998x_id[] = { 1566 + { "isl79987", 0 }, 1567 + { /* sentinel */ }, 1568 + }; 1569 + MODULE_DEVICE_TABLE(i2c, isl7998x_id); 1570 + 1571 + static int __maybe_unused isl7998x_runtime_resume(struct device *dev) 1572 + { 1573 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 1574 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 1575 + int ret; 1576 + 1577 + gpiod_set_value(isl7998x->rstb_gpio, 1); 1578 + gpiod_set_value(isl7998x->pd_gpio, 0); 1579 + gpiod_set_value(isl7998x->rstb_gpio, 0); 1580 + 1581 + ret = isl7998x_wait_power_on(isl7998x); 1582 + if (ret) 1583 + goto err; 1584 + 1585 + ret = isl7998x_init(isl7998x); 1586 + if (ret) 1587 + goto err; 1588 + 1589 + return 0; 1590 + 1591 + err: 1592 + gpiod_set_value(isl7998x->pd_gpio, 1); 1593 + 1594 + return ret; 1595 + } 1596 + 1597 + static int __maybe_unused isl7998x_runtime_suspend(struct device *dev) 1598 + { 1599 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 1600 + struct isl7998x *isl7998x = sd_to_isl7998x(sd); 1601 + 1602 + gpiod_set_value(isl7998x->pd_gpio, 1); 1603 + 1604 + return 0; 1605 + } 1606 + 1607 + static const struct dev_pm_ops isl7998x_pm_ops = { 1608 + SET_RUNTIME_PM_OPS(isl7998x_runtime_suspend, 1609 + isl7998x_runtime_resume, 1610 + NULL) 1611 + }; 1612 + 1613 + static struct i2c_driver isl7998x_i2c_driver = { 1614 + .driver = { 1615 + .name = "isl7998x", 1616 + .of_match_table = of_match_ptr(isl7998x_of_match), 1617 + .pm = &isl7998x_pm_ops, 1618 + }, 1619 + .probe_new = isl7998x_probe, 1620 + .remove = isl7998x_remove, 1621 + .id_table = isl7998x_id, 1622 + }; 1623 + 1624 + module_i2c_driver(isl7998x_i2c_driver); 1625 + 1626 + MODULE_DESCRIPTION("Intersil ISL7998x Analog to MIPI CSI-2/BT656 decoder"); 1627 + MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); 1628 + MODULE_LICENSE("GPL v2");
+2
drivers/media/i2c/m5mols/m5mols.h
··· 13 13 #define M5MOLS_H 14 14 15 15 #include <linux/sizes.h> 16 + #include <linux/gpio/consumer.h> 16 17 #include <media/v4l2-subdev.h> 17 18 #include "m5mols_reg.h" 18 19 ··· 225 224 struct v4l2_ctrl *jpeg_quality; 226 225 227 226 int (*set_power)(struct device *dev, int on); 227 + struct gpio_desc *reset; 228 228 229 229 struct mutex lock; 230 230
-1
drivers/media/i2c/m5mols/m5mols_capture.c
··· 15 15 #include <linux/irq.h> 16 16 #include <linux/interrupt.h> 17 17 #include <linux/delay.h> 18 - #include <linux/gpio.h> 19 18 #include <linux/regulator/consumer.h> 20 19 #include <linux/videodev2.h> 21 20 #include <media/v4l2-ctrls.h>
+10 -19
drivers/media/i2c/m5mols/m5mols_core.c
··· 14 14 #include <linux/irq.h> 15 15 #include <linux/interrupt.h> 16 16 #include <linux/delay.h> 17 - #include <linux/gpio.h> 17 + #include <linux/gpio/consumer.h> 18 18 #include <linux/regulator/consumer.h> 19 19 #include <linux/videodev2.h> 20 20 #include <linux/module.h> ··· 752 752 { 753 753 struct v4l2_subdev *sd = &info->sd; 754 754 struct i2c_client *client = v4l2_get_subdevdata(sd); 755 - const struct m5mols_platform_data *pdata = info->pdata; 756 755 int ret; 757 756 758 757 if (info->power == enable) ··· 771 772 return ret; 772 773 } 773 774 774 - gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity); 775 + gpiod_set_value(info->reset, 0); 775 776 info->power = 1; 776 777 777 778 return ret; ··· 784 785 if (info->set_power) 785 786 info->set_power(&client->dev, 0); 786 787 787 - gpio_set_value(pdata->gpio_reset, pdata->reset_polarity); 788 + gpiod_set_value(info->reset, 1); 788 789 789 790 info->isp_ready = 0; 790 791 info->power = 0; ··· 943 944 const struct i2c_device_id *id) 944 945 { 945 946 const struct m5mols_platform_data *pdata = client->dev.platform_data; 946 - unsigned long gpio_flags; 947 947 struct m5mols_info *info; 948 948 struct v4l2_subdev *sd; 949 949 int ret; 950 950 951 951 if (pdata == NULL) { 952 952 dev_err(&client->dev, "No platform data\n"); 953 - return -EINVAL; 954 - } 955 - 956 - if (!gpio_is_valid(pdata->gpio_reset)) { 957 - dev_err(&client->dev, "No valid RESET GPIO specified\n"); 958 953 return -EINVAL; 959 954 } 960 955 ··· 961 968 if (!info) 962 969 return -ENOMEM; 963 970 971 + /* This asserts reset, descriptor shall have polarity specified */ 972 + info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); 973 + if (IS_ERR(info->reset)) 974 + return PTR_ERR(info->reset); 975 + /* Notice: the "N" in M5MOLS_NRST implies active low */ 976 + gpiod_set_consumer_name(info->reset, "M5MOLS_NRST"); 977 + 964 978 info->pdata = pdata; 965 979 info->set_power = pdata->set_power; 966 - 967 - gpio_flags = pdata->reset_polarity 968 - ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; 969 - ret = devm_gpio_request_one(&client->dev, pdata->gpio_reset, gpio_flags, 970 - "M5MOLS_NRST"); 971 - if (ret) { 972 - dev_err(&client->dev, "Failed to request gpio: %d\n", ret); 973 - return ret; 974 - } 975 980 976 981 ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), 977 982 supplies);
-1
drivers/media/i2c/mt9m111.c
··· 9 9 #include <linux/slab.h> 10 10 #include <linux/i2c.h> 11 11 #include <linux/log2.h> 12 - #include <linux/gpio.h> 13 12 #include <linux/delay.h> 14 13 #include <linux/regulator/consumer.h> 15 14 #include <linux/v4l2-mediabus.h>
+35 -40
drivers/media/i2c/noon010pc30.c
··· 10 10 */ 11 11 12 12 #include <linux/delay.h> 13 - #include <linux/gpio.h> 13 + #include <linux/gpio/consumer.h> 14 14 #include <linux/i2c.h> 15 15 #include <linux/slab.h> 16 16 #include <linux/regulator/consumer.h> ··· 130 130 struct media_pad pad; 131 131 struct v4l2_ctrl_handler hdl; 132 132 struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES]; 133 - u32 gpio_nreset; 134 - u32 gpio_nstby; 133 + struct gpio_desc *reset; 134 + struct gpio_desc *stby; 135 135 136 136 /* Protects the struct members below */ 137 137 struct mutex lock; ··· 393 393 return 0; 394 394 } 395 395 396 - if (gpio_is_valid(info->gpio_nstby)) 397 - gpio_set_value(info->gpio_nstby, 0); 396 + /* Assert standby: line should be flagged active low in descriptor */ 397 + if (info->stby) 398 + gpiod_set_value(info->stby, 1); 398 399 399 - if (gpio_is_valid(info->gpio_nreset)) 400 - gpio_set_value(info->gpio_nreset, 0); 400 + /* Assert reset: line should be flagged active low in descriptor */ 401 + if (info->reset) 402 + gpiod_set_value(info->reset, 1); 401 403 402 404 ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply); 403 405 if (ret) 404 406 return ret; 405 407 406 - if (gpio_is_valid(info->gpio_nreset)) { 408 + /* De-assert reset and standby */ 409 + if (info->reset) { 407 410 msleep(50); 408 - gpio_set_value(info->gpio_nreset, 1); 411 + gpiod_set_value(info->reset, 0); 409 412 } 410 - if (gpio_is_valid(info->gpio_nstby)) { 413 + if (info->stby) { 411 414 udelay(1000); 412 - gpio_set_value(info->gpio_nstby, 1); 415 + gpiod_set_value(info->stby, 0); 413 416 } 414 - if (gpio_is_valid(info->gpio_nreset)) { 417 + /* Cycle reset: assert and deassert */ 418 + if (info->reset) { 415 419 udelay(1000); 416 - gpio_set_value(info->gpio_nreset, 0); 420 + gpiod_set_value(info->reset, 1); 417 421 msleep(100); 418 - gpio_set_value(info->gpio_nreset, 1); 422 + gpiod_set_value(info->reset, 0); 419 423 msleep(20); 420 424 } 421 425 info->power = 1; ··· 442 438 if (ret) 443 439 return ret; 444 440 445 - if (gpio_is_valid(info->gpio_nstby)) 446 - gpio_set_value(info->gpio_nstby, 0); 441 + /* Assert standby and reset */ 442 + if (info->stby) 443 + gpiod_set_value(info->stby, 1); 447 444 448 - if (gpio_is_valid(info->gpio_nreset)) 449 - gpio_set_value(info->gpio_nreset, 0); 445 + if (info->reset) 446 + gpiod_set_value(info->reset, 1); 450 447 451 448 info->power = 0; 452 449 ··· 746 741 goto np_err; 747 742 748 743 info->i2c_reg_page = -1; 749 - info->gpio_nreset = -EINVAL; 750 - info->gpio_nstby = -EINVAL; 751 744 info->curr_fmt = &noon010_formats[0]; 752 745 info->curr_win = &noon010_sizes[0]; 753 746 754 - if (gpio_is_valid(pdata->gpio_nreset)) { 755 - ret = devm_gpio_request_one(&client->dev, pdata->gpio_nreset, 756 - GPIOF_OUT_INIT_LOW, 757 - "NOON010PC30 NRST"); 758 - if (ret) { 759 - dev_err(&client->dev, "GPIO request error: %d\n", ret); 760 - goto np_err; 761 - } 762 - info->gpio_nreset = pdata->gpio_nreset; 763 - gpio_export(info->gpio_nreset, 0); 747 + /* Request reset asserted so we get put into reset */ 748 + info->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); 749 + if (IS_ERR(info->reset)) { 750 + ret = PTR_ERR(info->reset); 751 + goto np_err; 764 752 } 753 + gpiod_set_consumer_name(info->reset, "NOON010PC30 NRST"); 765 754 766 - if (gpio_is_valid(pdata->gpio_nstby)) { 767 - ret = devm_gpio_request_one(&client->dev, pdata->gpio_nstby, 768 - GPIOF_OUT_INIT_LOW, 769 - "NOON010PC30 NSTBY"); 770 - if (ret) { 771 - dev_err(&client->dev, "GPIO request error: %d\n", ret); 772 - goto np_err; 773 - } 774 - info->gpio_nstby = pdata->gpio_nstby; 775 - gpio_export(info->gpio_nstby, 0); 755 + /* Request standby asserted so we get put into standby */ 756 + info->stby = devm_gpiod_get(&client->dev, "standby", GPIOD_OUT_HIGH); 757 + if (IS_ERR(info->stby)) { 758 + ret = PTR_ERR(info->stby); 759 + goto np_err; 776 760 } 761 + gpiod_set_consumer_name(info->reset, "NOON010PC30 STBY"); 777 762 778 763 for (i = 0; i < NOON010_NUM_SUPPLIES; i++) 779 764 info->supply[i].supply = noon010_supply_name[i];
+1128
drivers/media/i2c/og01a1b.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2022 Intel Corporation. 3 + 4 + #include <asm/unaligned.h> 5 + #include <linux/acpi.h> 6 + #include <linux/delay.h> 7 + #include <linux/i2c.h> 8 + #include <linux/module.h> 9 + #include <linux/pm_runtime.h> 10 + #include <media/v4l2-ctrls.h> 11 + #include <media/v4l2-device.h> 12 + #include <media/v4l2-fwnode.h> 13 + 14 + #define OG01A1B_REG_VALUE_08BIT 1 15 + #define OG01A1B_REG_VALUE_16BIT 2 16 + #define OG01A1B_REG_VALUE_24BIT 3 17 + 18 + #define OG01A1B_LINK_FREQ_500MHZ 500000000ULL 19 + #define OG01A1B_SCLK 120000000LL 20 + #define OG01A1B_MCLK 19200000 21 + #define OG01A1B_DATA_LANES 2 22 + #define OG01A1B_RGB_DEPTH 10 23 + 24 + #define OG01A1B_REG_CHIP_ID 0x300a 25 + #define OG01A1B_CHIP_ID 0x470141 26 + 27 + #define OG01A1B_REG_MODE_SELECT 0x0100 28 + #define OG01A1B_MODE_STANDBY 0x00 29 + #define OG01A1B_MODE_STREAMING 0x01 30 + 31 + /* vertical-timings from sensor */ 32 + #define OG01A1B_REG_VTS 0x380e 33 + #define OG01A1B_VTS_120FPS 0x0498 34 + #define OG01A1B_VTS_120FPS_MIN 0x0498 35 + #define OG01A1B_VTS_MAX 0x7fff 36 + 37 + /* horizontal-timings from sensor */ 38 + #define OG01A1B_REG_HTS 0x380c 39 + 40 + /* Exposure controls from sensor */ 41 + #define OG01A1B_REG_EXPOSURE 0x3501 42 + #define OG01A1B_EXPOSURE_MIN 1 43 + #define OG01A1B_EXPOSURE_MAX_MARGIN 14 44 + #define OG01A1B_EXPOSURE_STEP 1 45 + 46 + /* Analog gain controls from sensor */ 47 + #define OG01A1B_REG_ANALOG_GAIN 0x3508 48 + #define OG01A1B_ANAL_GAIN_MIN 16 49 + #define OG01A1B_ANAL_GAIN_MAX 248 /* Max = 15.5x */ 50 + #define OG01A1B_ANAL_GAIN_STEP 1 51 + 52 + /* Digital gain controls from sensor */ 53 + #define OG01A1B_REG_DIG_GAIN 0x350a 54 + #define OG01A1B_DGTL_GAIN_MIN 1024 55 + #define OG01A1B_DGTL_GAIN_MAX 16384 /* Max = 16x */ 56 + #define OG01A1B_DGTL_GAIN_STEP 1 57 + #define OG01A1B_DGTL_GAIN_DEFAULT 1024 58 + 59 + /* Group Access */ 60 + #define OG01A1B_REG_GROUP_ACCESS 0x3208 61 + #define OG01A1B_GROUP_HOLD_START 0x0 62 + #define OG01A1B_GROUP_HOLD_END 0x10 63 + #define OG01A1B_GROUP_HOLD_LAUNCH 0xa0 64 + 65 + /* Test Pattern Control */ 66 + #define OG01A1B_REG_TEST_PATTERN 0x5100 67 + #define OG01A1B_TEST_PATTERN_ENABLE BIT(7) 68 + #define OG01A1B_TEST_PATTERN_BAR_SHIFT 2 69 + 70 + #define to_og01a1b(_sd) container_of(_sd, struct og01a1b, sd) 71 + 72 + enum { 73 + OG01A1B_LINK_FREQ_1000MBPS, 74 + }; 75 + 76 + struct og01a1b_reg { 77 + u16 address; 78 + u8 val; 79 + }; 80 + 81 + struct og01a1b_reg_list { 82 + u32 num_of_regs; 83 + const struct og01a1b_reg *regs; 84 + }; 85 + 86 + struct og01a1b_link_freq_config { 87 + const struct og01a1b_reg_list reg_list; 88 + }; 89 + 90 + struct og01a1b_mode { 91 + /* Frame width in pixels */ 92 + u32 width; 93 + 94 + /* Frame height in pixels */ 95 + u32 height; 96 + 97 + /* Horizontal timining size */ 98 + u32 hts; 99 + 100 + /* Default vertical timining size */ 101 + u32 vts_def; 102 + 103 + /* Min vertical timining size */ 104 + u32 vts_min; 105 + 106 + /* Link frequency needed for this resolution */ 107 + u32 link_freq_index; 108 + 109 + /* Sensor register settings for this resolution */ 110 + const struct og01a1b_reg_list reg_list; 111 + }; 112 + 113 + static const struct og01a1b_reg mipi_data_rate_1000mbps[] = { 114 + {0x0103, 0x01}, 115 + {0x0303, 0x02}, 116 + {0x0304, 0x00}, 117 + {0x0305, 0xd2}, 118 + {0x0323, 0x02}, 119 + {0x0324, 0x01}, 120 + {0x0325, 0x77}, 121 + }; 122 + 123 + static const struct og01a1b_reg mode_1280x1024_regs[] = { 124 + {0x0300, 0x0a}, 125 + {0x0301, 0x29}, 126 + {0x0302, 0x31}, 127 + {0x0303, 0x02}, 128 + {0x0304, 0x00}, 129 + {0x0305, 0xd2}, 130 + {0x0306, 0x00}, 131 + {0x0307, 0x01}, 132 + {0x0308, 0x02}, 133 + {0x0309, 0x00}, 134 + {0x0310, 0x00}, 135 + {0x0311, 0x00}, 136 + {0x0312, 0x07}, 137 + {0x0313, 0x00}, 138 + {0x0314, 0x00}, 139 + {0x0315, 0x00}, 140 + {0x0320, 0x02}, 141 + {0x0321, 0x01}, 142 + {0x0322, 0x01}, 143 + {0x0323, 0x02}, 144 + {0x0324, 0x01}, 145 + {0x0325, 0x77}, 146 + {0x0326, 0xce}, 147 + {0x0327, 0x04}, 148 + {0x0329, 0x02}, 149 + {0x032a, 0x04}, 150 + {0x032b, 0x04}, 151 + {0x032c, 0x02}, 152 + {0x032d, 0x01}, 153 + {0x032e, 0x00}, 154 + {0x300d, 0x02}, 155 + {0x300e, 0x04}, 156 + {0x3021, 0x08}, 157 + {0x301e, 0x03}, 158 + {0x3103, 0x00}, 159 + {0x3106, 0x08}, 160 + {0x3107, 0x40}, 161 + {0x3216, 0x01}, 162 + {0x3217, 0x00}, 163 + {0x3218, 0xc0}, 164 + {0x3219, 0x55}, 165 + {0x3500, 0x00}, 166 + {0x3501, 0x04}, 167 + {0x3502, 0x8a}, 168 + {0x3506, 0x01}, 169 + {0x3507, 0x72}, 170 + {0x3508, 0x01}, 171 + {0x3509, 0x00}, 172 + {0x350a, 0x01}, 173 + {0x350b, 0x00}, 174 + {0x350c, 0x00}, 175 + {0x3541, 0x00}, 176 + {0x3542, 0x40}, 177 + {0x3605, 0xe0}, 178 + {0x3606, 0x41}, 179 + {0x3614, 0x20}, 180 + {0x3620, 0x0b}, 181 + {0x3630, 0x07}, 182 + {0x3636, 0xa0}, 183 + {0x3637, 0xf9}, 184 + {0x3638, 0x09}, 185 + {0x3639, 0x38}, 186 + {0x363f, 0x09}, 187 + {0x3640, 0x17}, 188 + {0x3662, 0x04}, 189 + {0x3665, 0x80}, 190 + {0x3670, 0x68}, 191 + {0x3674, 0x00}, 192 + {0x3677, 0x3f}, 193 + {0x3679, 0x00}, 194 + {0x369f, 0x19}, 195 + {0x36a0, 0x03}, 196 + {0x36a2, 0x19}, 197 + {0x36a3, 0x03}, 198 + {0x370d, 0x66}, 199 + {0x370f, 0x00}, 200 + {0x3710, 0x03}, 201 + {0x3715, 0x03}, 202 + {0x3716, 0x03}, 203 + {0x3717, 0x06}, 204 + {0x3733, 0x00}, 205 + {0x3778, 0x00}, 206 + {0x37a8, 0x0f}, 207 + {0x37a9, 0x01}, 208 + {0x37aa, 0x07}, 209 + {0x37bd, 0x1c}, 210 + {0x37c1, 0x2f}, 211 + {0x37c3, 0x09}, 212 + {0x37c8, 0x1d}, 213 + {0x37ca, 0x30}, 214 + {0x37df, 0x00}, 215 + {0x3800, 0x00}, 216 + {0x3801, 0x00}, 217 + {0x3802, 0x00}, 218 + {0x3803, 0x00}, 219 + {0x3804, 0x05}, 220 + {0x3805, 0x0f}, 221 + {0x3806, 0x04}, 222 + {0x3807, 0x0f}, 223 + {0x3808, 0x05}, 224 + {0x3809, 0x00}, 225 + {0x380a, 0x04}, 226 + {0x380b, 0x00}, 227 + {0x380c, 0x03}, 228 + {0x380d, 0x50}, 229 + {0x380e, 0x04}, 230 + {0x380f, 0x98}, 231 + {0x3810, 0x00}, 232 + {0x3811, 0x08}, 233 + {0x3812, 0x00}, 234 + {0x3813, 0x08}, 235 + {0x3814, 0x11}, 236 + {0x3815, 0x11}, 237 + {0x3820, 0x40}, 238 + {0x3821, 0x04}, 239 + {0x3826, 0x00}, 240 + {0x3827, 0x00}, 241 + {0x382a, 0x08}, 242 + {0x382b, 0x52}, 243 + {0x382d, 0xba}, 244 + {0x383d, 0x14}, 245 + {0x384a, 0xa2}, 246 + {0x3866, 0x0e}, 247 + {0x3867, 0x07}, 248 + {0x3884, 0x00}, 249 + {0x3885, 0x08}, 250 + {0x3893, 0x68}, 251 + {0x3894, 0x2a}, 252 + {0x3898, 0x00}, 253 + {0x3899, 0x31}, 254 + {0x389a, 0x04}, 255 + {0x389b, 0x00}, 256 + {0x389c, 0x0b}, 257 + {0x389d, 0xad}, 258 + {0x389f, 0x08}, 259 + {0x38a0, 0x00}, 260 + {0x38a1, 0x00}, 261 + {0x38a8, 0x70}, 262 + {0x38ac, 0xea}, 263 + {0x38b2, 0x00}, 264 + {0x38b3, 0x08}, 265 + {0x38bc, 0x20}, 266 + {0x38c4, 0x0c}, 267 + {0x38c5, 0x3a}, 268 + {0x38c7, 0x3a}, 269 + {0x38e1, 0xc0}, 270 + {0x38ec, 0x3c}, 271 + {0x38f0, 0x09}, 272 + {0x38f1, 0x6f}, 273 + {0x38fe, 0x3c}, 274 + {0x391e, 0x00}, 275 + {0x391f, 0x00}, 276 + {0x3920, 0xa5}, 277 + {0x3921, 0x00}, 278 + {0x3922, 0x00}, 279 + {0x3923, 0x00}, 280 + {0x3924, 0x05}, 281 + {0x3925, 0x00}, 282 + {0x3926, 0x00}, 283 + {0x3927, 0x00}, 284 + {0x3928, 0x1a}, 285 + {0x3929, 0x01}, 286 + {0x392a, 0xb4}, 287 + {0x392b, 0x00}, 288 + {0x392c, 0x10}, 289 + {0x392f, 0x40}, 290 + {0x4000, 0xcf}, 291 + {0x4003, 0x40}, 292 + {0x4008, 0x00}, 293 + {0x4009, 0x07}, 294 + {0x400a, 0x02}, 295 + {0x400b, 0x54}, 296 + {0x400c, 0x00}, 297 + {0x400d, 0x07}, 298 + {0x4010, 0xc0}, 299 + {0x4012, 0x02}, 300 + {0x4014, 0x04}, 301 + {0x4015, 0x04}, 302 + {0x4017, 0x02}, 303 + {0x4042, 0x01}, 304 + {0x4306, 0x04}, 305 + {0x4307, 0x12}, 306 + {0x4509, 0x00}, 307 + {0x450b, 0x83}, 308 + {0x4604, 0x68}, 309 + {0x4608, 0x0a}, 310 + {0x4700, 0x06}, 311 + {0x4800, 0x64}, 312 + {0x481b, 0x3c}, 313 + {0x4825, 0x32}, 314 + {0x4833, 0x18}, 315 + {0x4837, 0x0f}, 316 + {0x4850, 0x40}, 317 + {0x4860, 0x00}, 318 + {0x4861, 0xec}, 319 + {0x4864, 0x00}, 320 + {0x4883, 0x00}, 321 + {0x4888, 0x90}, 322 + {0x4889, 0x05}, 323 + {0x488b, 0x04}, 324 + {0x4f00, 0x04}, 325 + {0x4f10, 0x04}, 326 + {0x4f21, 0x01}, 327 + {0x4f22, 0x40}, 328 + {0x4f23, 0x44}, 329 + {0x4f24, 0x51}, 330 + {0x4f25, 0x41}, 331 + {0x5000, 0x1f}, 332 + {0x500a, 0x00}, 333 + {0x5100, 0x00}, 334 + {0x5111, 0x20}, 335 + {0x3020, 0x20}, 336 + {0x3613, 0x03}, 337 + {0x38c9, 0x02}, 338 + {0x5304, 0x01}, 339 + {0x3620, 0x08}, 340 + {0x3639, 0x58}, 341 + {0x363a, 0x10}, 342 + {0x3674, 0x04}, 343 + {0x3780, 0xff}, 344 + {0x3781, 0xff}, 345 + {0x3782, 0x00}, 346 + {0x3783, 0x01}, 347 + {0x3798, 0xa3}, 348 + {0x37aa, 0x10}, 349 + {0x38a8, 0xf0}, 350 + {0x38c4, 0x09}, 351 + {0x38c5, 0xb0}, 352 + {0x38df, 0x80}, 353 + {0x38ff, 0x05}, 354 + {0x4010, 0xf1}, 355 + {0x4011, 0x70}, 356 + {0x3667, 0x80}, 357 + {0x4d00, 0x4a}, 358 + {0x4d01, 0x18}, 359 + {0x4d02, 0xbb}, 360 + {0x4d03, 0xde}, 361 + {0x4d04, 0x93}, 362 + {0x4d05, 0xff}, 363 + {0x4d09, 0x0a}, 364 + {0x37aa, 0x16}, 365 + {0x3606, 0x42}, 366 + {0x3605, 0x00}, 367 + {0x36a2, 0x17}, 368 + {0x300d, 0x0a}, 369 + {0x4d00, 0x4d}, 370 + {0x4d01, 0x95}, 371 + {0x3d8C, 0x70}, 372 + {0x3d8d, 0xE9}, 373 + {0x5300, 0x00}, 374 + {0x5301, 0x10}, 375 + {0x5302, 0x00}, 376 + {0x5303, 0xE3}, 377 + {0x3d88, 0x00}, 378 + {0x3d89, 0x10}, 379 + {0x3d8a, 0x00}, 380 + {0x3d8b, 0xE3}, 381 + {0x4f22, 0x00}, 382 + }; 383 + 384 + static const char * const og01a1b_test_pattern_menu[] = { 385 + "Disabled", 386 + "Standard Color Bar", 387 + "Top-Bottom Darker Color Bar", 388 + "Right-Left Darker Color Bar", 389 + "Bottom-Top Darker Color Bar" 390 + }; 391 + 392 + static const s64 link_freq_menu_items[] = { 393 + OG01A1B_LINK_FREQ_500MHZ, 394 + }; 395 + 396 + static const struct og01a1b_link_freq_config link_freq_configs[] = { 397 + [OG01A1B_LINK_FREQ_1000MBPS] = { 398 + .reg_list = { 399 + .num_of_regs = ARRAY_SIZE(mipi_data_rate_1000mbps), 400 + .regs = mipi_data_rate_1000mbps, 401 + } 402 + } 403 + }; 404 + 405 + static const struct og01a1b_mode supported_modes[] = { 406 + { 407 + .width = 1280, 408 + .height = 1024, 409 + .hts = 848, 410 + .vts_def = OG01A1B_VTS_120FPS, 411 + .vts_min = OG01A1B_VTS_120FPS_MIN, 412 + .reg_list = { 413 + .num_of_regs = ARRAY_SIZE(mode_1280x1024_regs), 414 + .regs = mode_1280x1024_regs, 415 + }, 416 + .link_freq_index = OG01A1B_LINK_FREQ_1000MBPS, 417 + }, 418 + }; 419 + 420 + struct og01a1b { 421 + struct v4l2_subdev sd; 422 + struct media_pad pad; 423 + struct v4l2_ctrl_handler ctrl_handler; 424 + 425 + /* V4L2 Controls */ 426 + struct v4l2_ctrl *link_freq; 427 + struct v4l2_ctrl *pixel_rate; 428 + struct v4l2_ctrl *vblank; 429 + struct v4l2_ctrl *hblank; 430 + struct v4l2_ctrl *exposure; 431 + 432 + /* Current mode */ 433 + const struct og01a1b_mode *cur_mode; 434 + 435 + /* To serialize asynchronus callbacks */ 436 + struct mutex mutex; 437 + 438 + /* Streaming on/off */ 439 + bool streaming; 440 + }; 441 + 442 + static u64 to_pixel_rate(u32 f_index) 443 + { 444 + u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OG01A1B_DATA_LANES; 445 + 446 + do_div(pixel_rate, OG01A1B_RGB_DEPTH); 447 + 448 + return pixel_rate; 449 + } 450 + 451 + static u64 to_pixels_per_line(u32 hts, u32 f_index) 452 + { 453 + u64 ppl = hts * to_pixel_rate(f_index); 454 + 455 + do_div(ppl, OG01A1B_SCLK); 456 + 457 + return ppl; 458 + } 459 + 460 + static int og01a1b_read_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 *val) 461 + { 462 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 463 + struct i2c_msg msgs[2]; 464 + u8 addr_buf[2]; 465 + u8 data_buf[4] = {0}; 466 + int ret; 467 + 468 + if (len > 4) 469 + return -EINVAL; 470 + 471 + put_unaligned_be16(reg, addr_buf); 472 + msgs[0].addr = client->addr; 473 + msgs[0].flags = 0; 474 + msgs[0].len = sizeof(addr_buf); 475 + msgs[0].buf = addr_buf; 476 + msgs[1].addr = client->addr; 477 + msgs[1].flags = I2C_M_RD; 478 + msgs[1].len = len; 479 + msgs[1].buf = &data_buf[4 - len]; 480 + 481 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 482 + if (ret != ARRAY_SIZE(msgs)) 483 + return -EIO; 484 + 485 + *val = get_unaligned_be32(data_buf); 486 + 487 + return 0; 488 + } 489 + 490 + static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val) 491 + { 492 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 493 + u8 buf[6]; 494 + 495 + if (len > 4) 496 + return -EINVAL; 497 + 498 + put_unaligned_be16(reg, buf); 499 + put_unaligned_be32(val << 8 * (4 - len), buf + 2); 500 + if (i2c_master_send(client, buf, len + 2) != len + 2) 501 + return -EIO; 502 + 503 + return 0; 504 + } 505 + 506 + static int og01a1b_write_reg_list(struct og01a1b *og01a1b, 507 + const struct og01a1b_reg_list *r_list) 508 + { 509 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 510 + unsigned int i; 511 + int ret; 512 + 513 + for (i = 0; i < r_list->num_of_regs; i++) { 514 + ret = og01a1b_write_reg(og01a1b, r_list->regs[i].address, 1, 515 + r_list->regs[i].val); 516 + if (ret) { 517 + dev_err_ratelimited(&client->dev, 518 + "failed to write reg 0x%4.4x. error = %d", 519 + r_list->regs[i].address, ret); 520 + return ret; 521 + } 522 + } 523 + 524 + return 0; 525 + } 526 + 527 + static int og01a1b_test_pattern(struct og01a1b *og01a1b, u32 pattern) 528 + { 529 + if (pattern) 530 + pattern = (pattern - 1) << OG01A1B_TEST_PATTERN_BAR_SHIFT | 531 + OG01A1B_TEST_PATTERN_ENABLE; 532 + 533 + return og01a1b_write_reg(og01a1b, OG01A1B_REG_TEST_PATTERN, 534 + OG01A1B_REG_VALUE_08BIT, pattern); 535 + } 536 + 537 + static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl) 538 + { 539 + struct og01a1b *og01a1b = container_of(ctrl->handler, 540 + struct og01a1b, ctrl_handler); 541 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 542 + s64 exposure_max; 543 + int ret = 0; 544 + 545 + /* Propagate change of current control to all related controls */ 546 + if (ctrl->id == V4L2_CID_VBLANK) { 547 + /* Update max exposure while meeting expected vblanking */ 548 + exposure_max = og01a1b->cur_mode->height + ctrl->val - 549 + OG01A1B_EXPOSURE_MAX_MARGIN; 550 + __v4l2_ctrl_modify_range(og01a1b->exposure, 551 + og01a1b->exposure->minimum, 552 + exposure_max, og01a1b->exposure->step, 553 + exposure_max); 554 + } 555 + 556 + /* V4L2 controls values will be applied only when power is already up */ 557 + if (!pm_runtime_get_if_in_use(&client->dev)) 558 + return 0; 559 + 560 + switch (ctrl->id) { 561 + case V4L2_CID_ANALOGUE_GAIN: 562 + ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_ANALOG_GAIN, 563 + OG01A1B_REG_VALUE_16BIT, 564 + ctrl->val << 4); 565 + break; 566 + 567 + case V4L2_CID_DIGITAL_GAIN: 568 + ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_DIG_GAIN, 569 + OG01A1B_REG_VALUE_24BIT, 570 + ctrl->val << 6); 571 + break; 572 + 573 + case V4L2_CID_EXPOSURE: 574 + ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_EXPOSURE, 575 + OG01A1B_REG_VALUE_16BIT, ctrl->val); 576 + break; 577 + 578 + case V4L2_CID_VBLANK: 579 + ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_VTS, 580 + OG01A1B_REG_VALUE_16BIT, 581 + og01a1b->cur_mode->height + ctrl->val); 582 + break; 583 + 584 + case V4L2_CID_TEST_PATTERN: 585 + ret = og01a1b_test_pattern(og01a1b, ctrl->val); 586 + break; 587 + 588 + default: 589 + ret = -EINVAL; 590 + break; 591 + } 592 + 593 + pm_runtime_put(&client->dev); 594 + 595 + return ret; 596 + } 597 + 598 + static const struct v4l2_ctrl_ops og01a1b_ctrl_ops = { 599 + .s_ctrl = og01a1b_set_ctrl, 600 + }; 601 + 602 + static int og01a1b_init_controls(struct og01a1b *og01a1b) 603 + { 604 + struct v4l2_ctrl_handler *ctrl_hdlr; 605 + s64 exposure_max, h_blank; 606 + int ret; 607 + 608 + ctrl_hdlr = &og01a1b->ctrl_handler; 609 + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8); 610 + if (ret) 611 + return ret; 612 + 613 + ctrl_hdlr->lock = &og01a1b->mutex; 614 + og01a1b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, 615 + &og01a1b_ctrl_ops, 616 + V4L2_CID_LINK_FREQ, 617 + ARRAY_SIZE 618 + (link_freq_menu_items) - 1, 619 + 0, link_freq_menu_items); 620 + if (og01a1b->link_freq) 621 + og01a1b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 622 + 623 + og01a1b->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, 624 + V4L2_CID_PIXEL_RATE, 0, 625 + to_pixel_rate 626 + (OG01A1B_LINK_FREQ_1000MBPS), 627 + 1, 628 + to_pixel_rate 629 + (OG01A1B_LINK_FREQ_1000MBPS)); 630 + og01a1b->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, 631 + V4L2_CID_VBLANK, 632 + og01a1b->cur_mode->vts_min - 633 + og01a1b->cur_mode->height, 634 + OG01A1B_VTS_MAX - 635 + og01a1b->cur_mode->height, 1, 636 + og01a1b->cur_mode->vts_def - 637 + og01a1b->cur_mode->height); 638 + h_blank = to_pixels_per_line(og01a1b->cur_mode->hts, 639 + og01a1b->cur_mode->link_freq_index) - 640 + og01a1b->cur_mode->width; 641 + og01a1b->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, 642 + V4L2_CID_HBLANK, h_blank, h_blank, 643 + 1, h_blank); 644 + if (og01a1b->hblank) 645 + og01a1b->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; 646 + 647 + v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, 648 + OG01A1B_ANAL_GAIN_MIN, OG01A1B_ANAL_GAIN_MAX, 649 + OG01A1B_ANAL_GAIN_STEP, OG01A1B_ANAL_GAIN_MIN); 650 + v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_DIGITAL_GAIN, 651 + OG01A1B_DGTL_GAIN_MIN, OG01A1B_DGTL_GAIN_MAX, 652 + OG01A1B_DGTL_GAIN_STEP, OG01A1B_DGTL_GAIN_DEFAULT); 653 + exposure_max = (og01a1b->cur_mode->vts_def - 654 + OG01A1B_EXPOSURE_MAX_MARGIN); 655 + og01a1b->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, 656 + V4L2_CID_EXPOSURE, 657 + OG01A1B_EXPOSURE_MIN, 658 + exposure_max, 659 + OG01A1B_EXPOSURE_STEP, 660 + exposure_max); 661 + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &og01a1b_ctrl_ops, 662 + V4L2_CID_TEST_PATTERN, 663 + ARRAY_SIZE(og01a1b_test_pattern_menu) - 1, 664 + 0, 0, og01a1b_test_pattern_menu); 665 + 666 + if (ctrl_hdlr->error) 667 + return ctrl_hdlr->error; 668 + 669 + og01a1b->sd.ctrl_handler = ctrl_hdlr; 670 + 671 + return 0; 672 + } 673 + 674 + static void og01a1b_update_pad_format(const struct og01a1b_mode *mode, 675 + struct v4l2_mbus_framefmt *fmt) 676 + { 677 + fmt->width = mode->width; 678 + fmt->height = mode->height; 679 + fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 680 + fmt->field = V4L2_FIELD_NONE; 681 + } 682 + 683 + static int og01a1b_start_streaming(struct og01a1b *og01a1b) 684 + { 685 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 686 + const struct og01a1b_reg_list *reg_list; 687 + int link_freq_index, ret; 688 + 689 + link_freq_index = og01a1b->cur_mode->link_freq_index; 690 + reg_list = &link_freq_configs[link_freq_index].reg_list; 691 + 692 + ret = og01a1b_write_reg_list(og01a1b, reg_list); 693 + if (ret) { 694 + dev_err(&client->dev, "failed to set plls"); 695 + return ret; 696 + } 697 + 698 + reg_list = &og01a1b->cur_mode->reg_list; 699 + ret = og01a1b_write_reg_list(og01a1b, reg_list); 700 + if (ret) { 701 + dev_err(&client->dev, "failed to set mode"); 702 + return ret; 703 + } 704 + 705 + ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler); 706 + if (ret) 707 + return ret; 708 + 709 + ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT, 710 + OG01A1B_REG_VALUE_08BIT, 711 + OG01A1B_MODE_STREAMING); 712 + if (ret) { 713 + dev_err(&client->dev, "failed to set stream"); 714 + return ret; 715 + } 716 + 717 + return 0; 718 + } 719 + 720 + static void og01a1b_stop_streaming(struct og01a1b *og01a1b) 721 + { 722 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 723 + 724 + if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT, 725 + OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY)) 726 + dev_err(&client->dev, "failed to set stream"); 727 + } 728 + 729 + static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable) 730 + { 731 + struct og01a1b *og01a1b = to_og01a1b(sd); 732 + struct i2c_client *client = v4l2_get_subdevdata(sd); 733 + int ret = 0; 734 + 735 + if (og01a1b->streaming == enable) 736 + return 0; 737 + 738 + mutex_lock(&og01a1b->mutex); 739 + if (enable) { 740 + ret = pm_runtime_get_sync(&client->dev); 741 + if (ret < 0) { 742 + pm_runtime_put_noidle(&client->dev); 743 + mutex_unlock(&og01a1b->mutex); 744 + return ret; 745 + } 746 + 747 + ret = og01a1b_start_streaming(og01a1b); 748 + if (ret) { 749 + enable = 0; 750 + og01a1b_stop_streaming(og01a1b); 751 + pm_runtime_put(&client->dev); 752 + } 753 + } else { 754 + og01a1b_stop_streaming(og01a1b); 755 + pm_runtime_put(&client->dev); 756 + } 757 + 758 + og01a1b->streaming = enable; 759 + mutex_unlock(&og01a1b->mutex); 760 + 761 + return ret; 762 + } 763 + 764 + static int __maybe_unused og01a1b_suspend(struct device *dev) 765 + { 766 + struct i2c_client *client = to_i2c_client(dev); 767 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 768 + struct og01a1b *og01a1b = to_og01a1b(sd); 769 + 770 + mutex_lock(&og01a1b->mutex); 771 + if (og01a1b->streaming) 772 + og01a1b_stop_streaming(og01a1b); 773 + 774 + mutex_unlock(&og01a1b->mutex); 775 + 776 + return 0; 777 + } 778 + 779 + static int __maybe_unused og01a1b_resume(struct device *dev) 780 + { 781 + struct i2c_client *client = to_i2c_client(dev); 782 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 783 + struct og01a1b *og01a1b = to_og01a1b(sd); 784 + int ret; 785 + 786 + mutex_lock(&og01a1b->mutex); 787 + if (og01a1b->streaming) { 788 + ret = og01a1b_start_streaming(og01a1b); 789 + if (ret) { 790 + og01a1b->streaming = false; 791 + og01a1b_stop_streaming(og01a1b); 792 + mutex_unlock(&og01a1b->mutex); 793 + return ret; 794 + } 795 + } 796 + 797 + mutex_unlock(&og01a1b->mutex); 798 + 799 + return 0; 800 + } 801 + 802 + static int og01a1b_set_format(struct v4l2_subdev *sd, 803 + struct v4l2_subdev_state *sd_state, 804 + struct v4l2_subdev_format *fmt) 805 + { 806 + struct og01a1b *og01a1b = to_og01a1b(sd); 807 + const struct og01a1b_mode *mode; 808 + s32 vblank_def, h_blank; 809 + 810 + mode = v4l2_find_nearest_size(supported_modes, 811 + ARRAY_SIZE(supported_modes), width, 812 + height, fmt->format.width, 813 + fmt->format.height); 814 + 815 + mutex_lock(&og01a1b->mutex); 816 + og01a1b_update_pad_format(mode, &fmt->format); 817 + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 818 + *v4l2_subdev_get_try_format(sd, sd_state, 819 + fmt->pad) = fmt->format; 820 + } else { 821 + og01a1b->cur_mode = mode; 822 + __v4l2_ctrl_s_ctrl(og01a1b->link_freq, mode->link_freq_index); 823 + __v4l2_ctrl_s_ctrl_int64(og01a1b->pixel_rate, 824 + to_pixel_rate(mode->link_freq_index)); 825 + 826 + /* Update limits and set FPS to default */ 827 + vblank_def = mode->vts_def - mode->height; 828 + __v4l2_ctrl_modify_range(og01a1b->vblank, 829 + mode->vts_min - mode->height, 830 + OG01A1B_VTS_MAX - mode->height, 1, 831 + vblank_def); 832 + __v4l2_ctrl_s_ctrl(og01a1b->vblank, vblank_def); 833 + h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - 834 + mode->width; 835 + __v4l2_ctrl_modify_range(og01a1b->hblank, h_blank, h_blank, 1, 836 + h_blank); 837 + } 838 + 839 + mutex_unlock(&og01a1b->mutex); 840 + 841 + return 0; 842 + } 843 + 844 + static int og01a1b_get_format(struct v4l2_subdev *sd, 845 + struct v4l2_subdev_state *sd_state, 846 + struct v4l2_subdev_format *fmt) 847 + { 848 + struct og01a1b *og01a1b = to_og01a1b(sd); 849 + 850 + mutex_lock(&og01a1b->mutex); 851 + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) 852 + fmt->format = *v4l2_subdev_get_try_format(&og01a1b->sd, 853 + sd_state, 854 + fmt->pad); 855 + else 856 + og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format); 857 + 858 + mutex_unlock(&og01a1b->mutex); 859 + 860 + return 0; 861 + } 862 + 863 + static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd, 864 + struct v4l2_subdev_state *sd_state, 865 + struct v4l2_subdev_mbus_code_enum *code) 866 + { 867 + if (code->index > 0) 868 + return -EINVAL; 869 + 870 + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; 871 + 872 + return 0; 873 + } 874 + 875 + static int og01a1b_enum_frame_size(struct v4l2_subdev *sd, 876 + struct v4l2_subdev_state *sd_state, 877 + struct v4l2_subdev_frame_size_enum *fse) 878 + { 879 + if (fse->index >= ARRAY_SIZE(supported_modes)) 880 + return -EINVAL; 881 + 882 + if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) 883 + return -EINVAL; 884 + 885 + fse->min_width = supported_modes[fse->index].width; 886 + fse->max_width = fse->min_width; 887 + fse->min_height = supported_modes[fse->index].height; 888 + fse->max_height = fse->min_height; 889 + 890 + return 0; 891 + } 892 + 893 + static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 894 + { 895 + struct og01a1b *og01a1b = to_og01a1b(sd); 896 + 897 + mutex_lock(&og01a1b->mutex); 898 + og01a1b_update_pad_format(&supported_modes[0], 899 + v4l2_subdev_get_try_format(sd, fh->state, 0)); 900 + mutex_unlock(&og01a1b->mutex); 901 + 902 + return 0; 903 + } 904 + 905 + static const struct v4l2_subdev_video_ops og01a1b_video_ops = { 906 + .s_stream = og01a1b_set_stream, 907 + }; 908 + 909 + static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = { 910 + .set_fmt = og01a1b_set_format, 911 + .get_fmt = og01a1b_get_format, 912 + .enum_mbus_code = og01a1b_enum_mbus_code, 913 + .enum_frame_size = og01a1b_enum_frame_size, 914 + }; 915 + 916 + static const struct v4l2_subdev_ops og01a1b_subdev_ops = { 917 + .video = &og01a1b_video_ops, 918 + .pad = &og01a1b_pad_ops, 919 + }; 920 + 921 + static const struct media_entity_operations og01a1b_subdev_entity_ops = { 922 + .link_validate = v4l2_subdev_link_validate, 923 + }; 924 + 925 + static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = { 926 + .open = og01a1b_open, 927 + }; 928 + 929 + static int og01a1b_identify_module(struct og01a1b *og01a1b) 930 + { 931 + struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd); 932 + int ret; 933 + u32 val; 934 + 935 + ret = og01a1b_read_reg(og01a1b, OG01A1B_REG_CHIP_ID, 936 + OG01A1B_REG_VALUE_24BIT, &val); 937 + if (ret) 938 + return ret; 939 + 940 + if (val != OG01A1B_CHIP_ID) { 941 + dev_err(&client->dev, "chip id mismatch: %x!=%x", 942 + OG01A1B_CHIP_ID, val); 943 + return -ENXIO; 944 + } 945 + 946 + return 0; 947 + } 948 + 949 + static int og01a1b_check_hwcfg(struct device *dev) 950 + { 951 + struct fwnode_handle *ep; 952 + struct fwnode_handle *fwnode = dev_fwnode(dev); 953 + struct v4l2_fwnode_endpoint bus_cfg = { 954 + .bus_type = V4L2_MBUS_CSI2_DPHY 955 + }; 956 + u32 mclk; 957 + int ret; 958 + unsigned int i, j; 959 + 960 + if (!fwnode) 961 + return -ENXIO; 962 + 963 + ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); 964 + 965 + if (ret) { 966 + dev_err(dev, "can't get clock frequency"); 967 + return ret; 968 + } 969 + 970 + if (mclk != OG01A1B_MCLK) { 971 + dev_err(dev, "external clock %d is not supported", mclk); 972 + return -EINVAL; 973 + } 974 + 975 + ep = fwnode_graph_get_next_endpoint(fwnode, NULL); 976 + if (!ep) 977 + return -ENXIO; 978 + 979 + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); 980 + fwnode_handle_put(ep); 981 + if (ret) 982 + return ret; 983 + 984 + if (bus_cfg.bus.mipi_csi2.num_data_lanes != OG01A1B_DATA_LANES) { 985 + dev_err(dev, "number of CSI2 data lanes %d is not supported", 986 + bus_cfg.bus.mipi_csi2.num_data_lanes); 987 + ret = -EINVAL; 988 + goto check_hwcfg_error; 989 + } 990 + 991 + if (!bus_cfg.nr_of_link_frequencies) { 992 + dev_err(dev, "no link frequencies defined"); 993 + ret = -EINVAL; 994 + goto check_hwcfg_error; 995 + } 996 + 997 + for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { 998 + for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { 999 + if (link_freq_menu_items[i] == 1000 + bus_cfg.link_frequencies[j]) 1001 + break; 1002 + } 1003 + 1004 + if (j == bus_cfg.nr_of_link_frequencies) { 1005 + dev_err(dev, "no link frequency %lld supported", 1006 + link_freq_menu_items[i]); 1007 + ret = -EINVAL; 1008 + goto check_hwcfg_error; 1009 + } 1010 + } 1011 + 1012 + check_hwcfg_error: 1013 + v4l2_fwnode_endpoint_free(&bus_cfg); 1014 + 1015 + return ret; 1016 + } 1017 + 1018 + static int og01a1b_remove(struct i2c_client *client) 1019 + { 1020 + struct v4l2_subdev *sd = i2c_get_clientdata(client); 1021 + struct og01a1b *og01a1b = to_og01a1b(sd); 1022 + 1023 + v4l2_async_unregister_subdev(sd); 1024 + media_entity_cleanup(&sd->entity); 1025 + v4l2_ctrl_handler_free(sd->ctrl_handler); 1026 + pm_runtime_disable(&client->dev); 1027 + mutex_destroy(&og01a1b->mutex); 1028 + 1029 + return 0; 1030 + } 1031 + 1032 + static int og01a1b_probe(struct i2c_client *client) 1033 + { 1034 + struct og01a1b *og01a1b; 1035 + int ret; 1036 + 1037 + ret = og01a1b_check_hwcfg(&client->dev); 1038 + if (ret) { 1039 + dev_err(&client->dev, "failed to check HW configuration: %d", 1040 + ret); 1041 + return ret; 1042 + } 1043 + 1044 + og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL); 1045 + if (!og01a1b) 1046 + return -ENOMEM; 1047 + 1048 + v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops); 1049 + ret = og01a1b_identify_module(og01a1b); 1050 + if (ret) { 1051 + dev_err(&client->dev, "failed to find sensor: %d", ret); 1052 + return ret; 1053 + } 1054 + 1055 + mutex_init(&og01a1b->mutex); 1056 + og01a1b->cur_mode = &supported_modes[0]; 1057 + ret = og01a1b_init_controls(og01a1b); 1058 + if (ret) { 1059 + dev_err(&client->dev, "failed to init controls: %d", ret); 1060 + goto probe_error_v4l2_ctrl_handler_free; 1061 + } 1062 + 1063 + og01a1b->sd.internal_ops = &og01a1b_internal_ops; 1064 + og01a1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 1065 + og01a1b->sd.entity.ops = &og01a1b_subdev_entity_ops; 1066 + og01a1b->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; 1067 + og01a1b->pad.flags = MEDIA_PAD_FL_SOURCE; 1068 + ret = media_entity_pads_init(&og01a1b->sd.entity, 1, &og01a1b->pad); 1069 + if (ret) { 1070 + dev_err(&client->dev, "failed to init entity pads: %d", ret); 1071 + goto probe_error_v4l2_ctrl_handler_free; 1072 + } 1073 + 1074 + ret = v4l2_async_register_subdev_sensor(&og01a1b->sd); 1075 + if (ret < 0) { 1076 + dev_err(&client->dev, "failed to register V4L2 subdev: %d", 1077 + ret); 1078 + goto probe_error_media_entity_cleanup; 1079 + } 1080 + 1081 + /* 1082 + * Device is already turned on by i2c-core with ACPI domain PM. 1083 + * Enable runtime PM and turn off the device. 1084 + */ 1085 + pm_runtime_set_active(&client->dev); 1086 + pm_runtime_enable(&client->dev); 1087 + pm_runtime_idle(&client->dev); 1088 + 1089 + return 0; 1090 + 1091 + probe_error_media_entity_cleanup: 1092 + media_entity_cleanup(&og01a1b->sd.entity); 1093 + 1094 + probe_error_v4l2_ctrl_handler_free: 1095 + v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler); 1096 + mutex_destroy(&og01a1b->mutex); 1097 + 1098 + return ret; 1099 + } 1100 + 1101 + static const struct dev_pm_ops og01a1b_pm_ops = { 1102 + SET_SYSTEM_SLEEP_PM_OPS(og01a1b_suspend, og01a1b_resume) 1103 + }; 1104 + 1105 + #ifdef CONFIG_ACPI 1106 + static const struct acpi_device_id og01a1b_acpi_ids[] = { 1107 + {"OVTI01AC"}, 1108 + {} 1109 + }; 1110 + 1111 + MODULE_DEVICE_TABLE(acpi, og01a1b_acpi_ids); 1112 + #endif 1113 + 1114 + static struct i2c_driver og01a1b_i2c_driver = { 1115 + .driver = { 1116 + .name = "og01a1b", 1117 + .pm = &og01a1b_pm_ops, 1118 + .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids), 1119 + }, 1120 + .probe_new = og01a1b_probe, 1121 + .remove = og01a1b_remove, 1122 + }; 1123 + 1124 + module_i2c_driver(og01a1b_i2c_driver); 1125 + 1126 + MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>"); 1127 + MODULE_DESCRIPTION("OmniVision OG01A1B sensor driver"); 1128 + MODULE_LICENSE("GPL v2");
+7 -7
drivers/media/i2c/ov5640.c
··· 2293 2293 struct ov5640_dev *sensor = to_ov5640_dev(sd); 2294 2294 const struct ov5640_mode_info *new_mode; 2295 2295 struct v4l2_mbus_framefmt *mbus_fmt = &format->format; 2296 - struct v4l2_mbus_framefmt *fmt; 2297 2296 int ret; 2298 2297 2299 2298 if (format->pad != 0) ··· 2310 2311 if (ret) 2311 2312 goto out; 2312 2313 2313 - if (format->which == V4L2_SUBDEV_FORMAT_TRY) 2314 - fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); 2315 - else 2316 - fmt = &sensor->fmt; 2317 - 2318 - *fmt = *mbus_fmt; 2314 + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 2315 + *v4l2_subdev_get_try_format(sd, sd_state, 0) = *mbus_fmt; 2316 + goto out; 2317 + } 2319 2318 2320 2319 if (new_mode != sensor->current_mode) { 2321 2320 sensor->current_mode = new_mode; ··· 2321 2324 } 2322 2325 if (mbus_fmt->code != sensor->fmt.code) 2323 2326 sensor->pending_fmt_change = true; 2327 + 2328 + /* update format even if code is unchanged, resolution might change */ 2329 + sensor->fmt = *mbus_fmt; 2324 2330 2325 2331 __v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, 2326 2332 ov5640_calc_pixel_rate(sensor));
+8 -2
drivers/media/i2c/ov5648.c
··· 1778 1778 1779 1779 static int ov5648_state_init(struct ov5648_sensor *sensor) 1780 1780 { 1781 - return ov5648_state_configure(sensor, &ov5648_modes[0], 1782 - ov5648_mbus_codes[0]); 1781 + int ret; 1782 + 1783 + mutex_lock(&sensor->mutex); 1784 + ret = ov5648_state_configure(sensor, &ov5648_modes[0], 1785 + ov5648_mbus_codes[0]); 1786 + mutex_unlock(&sensor->mutex); 1787 + 1788 + return ret; 1783 1789 } 1784 1790 1785 1791 /* Sensor Base */
+2 -2
drivers/media/i2c/ov8865.c
··· 457 457 458 458 #define OV8865_NATIVE_WIDTH 3296 459 459 #define OV8865_NATIVE_HEIGHT 2528 460 - #define OV8865_ACTIVE_START_TOP 32 461 - #define OV8865_ACTIVE_START_LEFT 80 460 + #define OV8865_ACTIVE_START_LEFT 16 461 + #define OV8865_ACTIVE_START_TOP 40 462 462 #define OV8865_ACTIVE_WIDTH 3264 463 463 #define OV8865_ACTIVE_HEIGHT 2448 464 464
+24 -31
drivers/media/mc/mc-entity.c
··· 396 396 struct media_link *link; 397 397 int ret; 398 398 399 - if (!pipe->streaming_count++) { 400 - ret = media_graph_walk_init(&pipe->graph, mdev); 401 - if (ret) 402 - goto error_graph_walk_start; 399 + if (pipe->streaming_count) { 400 + pipe->streaming_count++; 401 + return 0; 403 402 } 403 + 404 + ret = media_graph_walk_init(&pipe->graph, mdev); 405 + if (ret) 406 + return ret; 404 407 405 408 media_graph_walk_start(&pipe->graph, entity); 406 409 407 410 while ((entity = media_graph_walk_next(graph))) { 408 411 DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); 409 412 DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); 410 - 411 - entity->stream_count++; 412 413 413 414 if (entity->pipe && entity->pipe != pipe) { 414 415 pr_err("Pipe active for %s. Can't start for %s\n", ··· 419 418 goto error; 420 419 } 421 420 422 - entity->pipe = pipe; 423 - 424 421 /* Already streaming --- no need to check. */ 425 - if (entity->stream_count > 1) 422 + if (entity->pipe) 426 423 continue; 424 + 425 + entity->pipe = pipe; 427 426 428 427 if (!entity->ops || !entity->ops->link_validate) 429 428 continue; ··· 480 479 } 481 480 } 482 481 482 + pipe->streaming_count++; 483 + 483 484 return 0; 484 485 485 486 error: ··· 492 489 media_graph_walk_start(graph, entity_err); 493 490 494 491 while ((entity_err = media_graph_walk_next(graph))) { 495 - /* Sanity check for negative stream_count */ 496 - if (!WARN_ON_ONCE(entity_err->stream_count <= 0)) { 497 - entity_err->stream_count--; 498 - if (entity_err->stream_count == 0) 499 - entity_err->pipe = NULL; 500 - } 492 + entity_err->pipe = NULL; 501 493 502 494 /* 503 - * We haven't increased stream_count further than this 504 - * so we quit here. 495 + * We haven't started entities further than this so we quit 496 + * here. 505 497 */ 506 498 if (entity_err == entity) 507 499 break; 508 500 } 509 501 510 - error_graph_walk_start: 511 - if (!--pipe->streaming_count) 512 - media_graph_walk_cleanup(graph); 502 + media_graph_walk_cleanup(graph); 513 503 514 504 return ret; 515 505 } ··· 533 537 if (WARN_ON(!pipe)) 534 538 return; 535 539 540 + if (--pipe->streaming_count) 541 + return; 542 + 536 543 media_graph_walk_start(graph, entity); 537 544 538 - while ((entity = media_graph_walk_next(graph))) { 539 - /* Sanity check for negative stream_count */ 540 - if (!WARN_ON_ONCE(entity->stream_count <= 0)) { 541 - entity->stream_count--; 542 - if (entity->stream_count == 0) 543 - entity->pipe = NULL; 544 - } 545 - } 545 + while ((entity = media_graph_walk_next(graph))) 546 + entity->pipe = NULL; 546 547 547 - if (!--pipe->streaming_count) 548 - media_graph_walk_cleanup(graph); 548 + media_graph_walk_cleanup(graph); 549 549 550 550 } 551 551 EXPORT_SYMBOL_GPL(__media_pipeline_stop); ··· 826 834 sink = link->sink->entity; 827 835 828 836 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && 829 - (source->stream_count || sink->stream_count)) 837 + (media_entity_is_streaming(source) || 838 + media_entity_is_streaming(sink))) 830 839 return -EBUSY; 831 840 832 841 mdev = source->graph_obj.mdev;
+4 -1
drivers/media/platform/exynos4-is/common.c
··· 10 10 #include <media/drv-intf/exynos-fimc.h> 11 11 #include "common.h" 12 12 13 - /* Called with the media graph mutex held or entity->stream_count > 0. */ 13 + /* 14 + * Called with the media graph mutex held or media_entity_is_streaming(entity) 15 + * true. 16 + */ 14 17 struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity) 15 18 { 16 19 struct media_pad *pad = &entity->pads[0];
+1 -1
drivers/media/platform/exynos4-is/fimc-isp.c
··· 226 226 } 227 227 } 228 228 } else { 229 - if (sd->entity.stream_count == 0) { 229 + if (!media_entity_is_streaming(&sd->entity)) { 230 230 if (fmt->pad == FIMC_ISP_SD_PAD_SINK) { 231 231 struct v4l2_subdev_format format = *fmt; 232 232
+3 -3
drivers/media/platform/exynos4-is/fimc-lite.c
··· 1073 1073 mutex_lock(&fimc->lock); 1074 1074 1075 1075 if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP && 1076 - sd->entity.stream_count > 0) || 1076 + media_entity_is_streaming(&sd->entity)) || 1077 1077 (atomic_read(&fimc->out_path) == FIMC_IO_DMA && 1078 1078 vb2_is_busy(&fimc->vb_queue))) { 1079 1079 mutex_unlock(&fimc->lock); ··· 1197 1197 * Find sensor subdev linked to FIMC-LITE directly or through 1198 1198 * MIPI-CSIS. This is required for configuration where FIMC-LITE 1199 1199 * is used as a subdev only and feeds data internally to FIMC-IS. 1200 - * The pipeline links are protected through entity.stream_count 1201 - * so there is no need to take the media graph mutex here. 1200 + * The pipeline links are protected through entity.pipe so there is no 1201 + * need to take the media graph mutex here. 1202 1202 */ 1203 1203 fimc->sensor = fimc_find_remote_sensor(&sd->entity); 1204 1204
+1 -1
drivers/media/platform/rcar-vin/rcar-core.c
··· 793 793 * running streams. 794 794 */ 795 795 media_device_for_each_entity(entity, &group->mdev) 796 - if (entity->stream_count) 796 + if (media_entity_is_streaming(entity)) 797 797 return -EBUSY; 798 798 799 799 /* Find the master VIN that controls the routes. */
+8 -20
drivers/media/v4l2-core/v4l2-fwnode.c
··· 894 894 int ret; 895 895 896 896 for (index = 0; 897 - !(ret = fwnode_property_get_reference_args(dev_fwnode(dev), 898 - prop, NULL, 0, 899 - index, &args)); 900 - index++) 901 - fwnode_handle_put(args.fwnode); 902 - 903 - if (!index) 904 - return -ENOENT; 905 - 906 - /* 907 - * Note that right now both -ENODATA and -ENOENT may signal 908 - * out-of-bounds access. Return the error in cases other than that. 909 - */ 910 - if (ret != -ENOENT && ret != -ENODATA) 911 - return ret; 912 - 913 - for (index = 0; 914 - !fwnode_property_get_reference_args(dev_fwnode(dev), prop, NULL, 915 - 0, index, &args); 897 + !(ret = fwnode_property_get_reference_args(dev_fwnode(dev), prop, 898 + NULL, 0, index, &args)); 916 899 index++) { 917 900 struct v4l2_async_subdev *asd; 918 901 ··· 911 928 } 912 929 } 913 930 914 - return 0; 931 + /* -ENOENT here means successful parsing */ 932 + if (ret != -ENOENT) 933 + return ret; 934 + 935 + /* Return -ENOENT if no references were found */ 936 + return index ? 0 : -ENOENT; 915 937 } 916 938 917 939 /*
-4
include/media/i2c/m5mols.h
··· 14 14 15 15 /** 16 16 * struct m5mols_platform_data - platform data for M-5MOLS driver 17 - * @gpio_reset: GPIO driving the reset pin of M-5MOLS 18 - * @reset_polarity: active state for gpio_reset pin, 0 or 1 19 17 * @set_power: an additional callback to the board setup code 20 18 * to be called after enabling and before disabling 21 19 * the sensor's supply regulators 22 20 */ 23 21 struct m5mols_platform_data { 24 - int gpio_reset; 25 - u8 reset_polarity; 26 22 int (*set_power)(struct device *dev, int on); 27 23 }; 28 24
-4
include/media/i2c/noon010pc30.h
··· 12 12 /** 13 13 * struct noon010pc30_platform_data - platform data 14 14 * @clk_rate: the clock frequency in Hz 15 - * @gpio_nreset: GPIO driving nRESET pin 16 - * @gpio_nstby: GPIO driving nSTBY pin 17 15 */ 18 16 19 17 struct noon010pc30_platform_data { 20 18 unsigned long clk_rate; 21 - int gpio_nreset; 22 - int gpio_nstby; 23 19 }; 24 20 25 21 #endif /* NOON010PC30_H */
+19 -6
include/media/media-entity.h
··· 268 268 * @pads: Pads array with the size defined by @num_pads. 269 269 * @links: List of data links. 270 270 * @ops: Entity operations. 271 - * @stream_count: Stream count for the entity. 272 271 * @use_count: Use count for the entity. 273 272 * @pipe: Pipeline this entity belongs to. 274 273 * @info: Union with devnode information. Kept just for backward ··· 282 283 * 283 284 * .. note:: 284 285 * 285 - * @stream_count and @use_count reference counts must never be 286 - * negative, but are signed integers on purpose: a simple ``WARN_ON(<0)`` 287 - * check can be used to detect reference count bugs that would make them 288 - * negative. 286 + * The @use_count reference count must never be negative, but is a signed 287 + * integer on purpose: a simple ``WARN_ON(<0)`` check can be used to detect 288 + * reference count bugs that would make it negative. 289 289 */ 290 290 struct media_entity { 291 291 struct media_gobj graph_obj; /* must be first field in struct */ ··· 303 305 304 306 const struct media_entity_operations *ops; 305 307 306 - int stream_count; 307 308 int use_count; 308 309 309 310 struct media_pipeline *pipe; ··· 654 657 * 655 658 * This function must be called during the cleanup phase after unregistering 656 659 * the entity (currently, it does nothing). 660 + * 661 + * Calling media_entity_cleanup() on a media_entity whose memory has been 662 + * zeroed but that has not been initialized with media_entity_pad_init() is 663 + * valid and is a no-op. 657 664 */ 658 665 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) 659 666 static inline void media_entity_cleanup(struct media_entity *entity) {} ··· 858 857 * enabled link, or %NULL if no enabled link has been found. 859 858 */ 860 859 struct media_pad *media_entity_remote_pad(const struct media_pad *pad); 860 + 861 + /** 862 + * media_entity_is_streaming - Test if an entity is part of a streaming pipeline 863 + * @entity: The entity 864 + * 865 + * Return: True if the entity is part of a pipeline started with the 866 + * media_pipeline_start() function, false otherwise. 867 + */ 868 + static inline bool media_entity_is_streaming(const struct media_entity *entity) 869 + { 870 + return entity->pipe; 871 + } 861 872 862 873 /** 863 874 * media_entity_get_fwnode_pad - Get pad number from fwnode
+6
include/uapi/linux/v4l2-controls.h
··· 219 219 */ 220 220 #define V4L2_CID_USER_ALLEGRO_BASE (V4L2_CID_USER_BASE + 0x1170) 221 221 222 + /* 223 + * The base for the isl7998x driver controls. 224 + * We reserve 16 controls for this driver. 225 + */ 226 + #define V4L2_CID_USER_ISL7998X_BASE (V4L2_CID_USER_BASE + 0x1180) 227 + 222 228 /* MPEG-class control IDs */ 223 229 /* The MPEG controls are applicable to all codec controls 224 230 * and the 'MPEG' part of the define is historical */