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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'media/v6.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull missed media updates from Mauro Carvalho Chehab:
"It seems I screwed-up my previous pull request: it ends up that only
half of the media patches that were in linux-next got merged in -rc1.

The script which creates the signed tags silently failed due to
5.19->6.0 so it ended generating a tag with incomplete stuff.

So here are the missing parts:

- a DVB core security fix

- lots of fixes and cleanups for atomisp staging driver

- old drivers that are VB1 are being moved to staging to be
deprecated

- several driver updates - mostly for embedded systems, but there are
also some things addressing issues with some PC webcams, in the UVC
video driver"

* tag 'media/v6.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (163 commits)
media: sun6i-csi: Move csi buffer definition to main header file
media: sun6i-csi: Introduce and use video helper functions
media: sun6i-csi: Add media ops with link notify callback
media: sun6i-csi: Remove controls handler from the driver
media: sun6i-csi: Register the media device after creation
media: sun6i-csi: Pass and store csi device directly in video code
media: sun6i-csi: Tidy up video code
media: sun6i-csi: Tidy up v4l2 code
media: sun6i-csi: Tidy up Kconfig
media: sun6i-csi: Use runtime pm for clocks and reset
media: sun6i-csi: Define and use variant to get module clock rate
media: sun6i-csi: Always set exclusive module clock rate
media: sun6i-csi: Tidy up platform code
media: sun6i-csi: Refactor main driver data structures
media: sun6i-csi: Define and use driver name and (reworked) description
media: cedrus: Add a Kconfig dependency on RESET_CONTROLLER
media: sun8i-rotate: Add a Kconfig dependency on RESET_CONTROLLER
media: sun8i-di: Add a Kconfig dependency on RESET_CONTROLLER
media: sun4i-csi: Add a Kconfig dependency on RESET_CONTROLLER
media: sun6i-csi: Add a Kconfig dependency on RESET_CONTROLLER
...

+3216 -3896
-9
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt
··· 1 - Dongwoon Anatech DW9714 camera voice coil lens driver 2 - 3 - DW9174 is a 10-bit DAC with current sink capability. It is intended 4 - for driving voice coil lenses in camera modules. 5 - 6 - Mandatory properties: 7 - 8 - - compatible: "dongwoon,dw9714" 9 - - reg: I²C slave address
+47
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.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/dongwoon,dw9714.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Dongwoon Anatech DW9714 camera voice coil lens driver 8 + 9 + maintainers: 10 + - Krzysztof Kozlowski <krzk@kernel.org> 11 + 12 + description: 13 + DW9174 is a 10-bit DAC with current sink capability. It is intended for 14 + driving voice coil lenses in camera modules. 15 + 16 + properties: 17 + compatible: 18 + const: dongwoon,dw9714 19 + 20 + reg: 21 + maxItems: 1 22 + 23 + powerdown-gpios: 24 + description: 25 + XSD pin for shutdown (active low) 26 + 27 + vcc-supply: 28 + description: VDD power supply 29 + 30 + required: 31 + - compatible 32 + - reg 33 + 34 + additionalProperties: false 35 + 36 + examples: 37 + - | 38 + i2c { 39 + #address-cells = <1>; 40 + #size-cells = <0>; 41 + 42 + camera-lens@c { 43 + compatible = "dongwoon,dw9714"; 44 + reg = <0x0c>; 45 + vcc-supply = <&reg_csi_1v8>; 46 + }; 47 + };
+15 -4
Documentation/driver-api/media/mc-core.rst
··· 214 214 Pipelines and media streams 215 215 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 216 216 217 + A media stream is a stream of pixels or metadata originating from one or more 218 + source devices (such as a sensors) and flowing through media entity pads 219 + towards the final sinks. The stream can be modified on the route by the 220 + devices (e.g. scaling or pixel format conversions), or it can be split into 221 + multiple branches, or multiple branches can be merged. 222 + 223 + A media pipeline is a set of media streams which are interdependent. This 224 + interdependency can be caused by the hardware (e.g. configuration of a second 225 + stream cannot be changed if the first stream has been enabled) or by the driver 226 + due to the software design. Most commonly a media pipeline consists of a single 227 + stream which does not branch. 228 + 217 229 When starting streaming, drivers must notify all entities in the pipeline to 218 230 prevent link states from being modified during streaming by calling 219 231 :c:func:`media_pipeline_start()`. 220 232 221 - The function will mark all entities connected to the given entity through 222 - enabled links, either directly or indirectly, as streaming. 233 + The function will mark all the pads which are part of the pipeline as streaming. 223 234 224 235 The struct media_pipeline instance pointed to by 225 - the pipe argument will be stored in every entity in the pipeline. 236 + the pipe argument will be stored in every pad in the pipeline. 226 237 Drivers should embed the struct media_pipeline 227 238 in higher-level pipeline structures and can then access the 228 - pipeline through the struct media_entity 239 + pipeline through the struct media_pad 229 240 pipe field. 230 241 231 242 Calls to :c:func:`media_pipeline_start()` can be nested.
+2
Documentation/userspace-api/media/cec.h.rst.exceptions
··· 239 239 ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 240 240 ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 241 241 ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 242 + ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_VOLUME_LEVEL 242 243 243 244 ignore define CEC_MSG_GIVE_FEATURES 244 245 ··· 488 487 489 488 ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 490 489 ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 490 + ignore define CEC_MSG_SET_AUDIO_VOLUME_LEVEL 491 491 492 492 ignore define CEC_OP_AUD_FMT_ID_CEA861 493 493 ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT
+2 -2
Documentation/userspace-api/media/v4l/libv4l-introduction.rst
··· 136 136 137 137 operates like the :c:func:`read()` function. 138 138 139 - .. c:function:: void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset); 139 + .. c:function:: void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset); 140 140 141 - operates like the :c:func:`munmap()` function. 141 + operates like the :c:func:`mmap()` function. 142 142 143 143 .. c:function:: int v4l2_munmap(void *_start, size_t length); 144 144
+2 -3
MAINTAINERS
··· 6284 6284 L: linux-media@vger.kernel.org 6285 6285 S: Maintained 6286 6286 T: git git://linuxtv.org/media_tree.git 6287 - F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt 6287 + F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml 6288 6288 F: drivers/media/i2c/dw9714.c 6289 6289 6290 6290 DONGWOON DW9768 LENS VOICE COIL DRIVER ··· 18141 18141 S: Maintained 18142 18142 T: git git://linuxtv.org/media_tree.git 18143 18143 F: drivers/staging/media/deprecated/saa7146/ 18144 - F: include/media/drv-intf/saa7146* 18145 18144 18146 18145 SAFESETID SECURITY MODULE 18147 18146 M: Micah Morton <mortonm@chromium.org> ··· 22770 22771 W: http://mjpeg.sourceforge.net/driver-zoran/ 22771 22772 Q: https://patchwork.linuxtv.org/project/linux-media/list/ 22772 22773 F: Documentation/driver-api/media/drivers/zoran.rst 22773 - F: drivers/staging/media/zoran/ 22774 + F: drivers/media/pci/zoran/ 22774 22775 22775 22776 ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER 22776 22777 M: Minchan Kim <minchan@kernel.org>
+1 -1
drivers/media/Kconfig
··· 24 24 25 25 config MEDIA_SUPPORT_FILTER 26 26 bool "Filter media drivers" 27 - default y if !EMBEDDED && !EXPERT 27 + default y if !EXPERT 28 28 help 29 29 Configuring the media subsystem can be complex, as there are 30 30 hundreds of drivers and other config options.
+1
drivers/media/cec/core/cec-adap.c
··· 1027 1027 [CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, 1028 1028 [CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED, 1029 1029 [CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH, 1030 + [CEC_MSG_SET_AUDIO_VOLUME_LEVEL] = 3 | DIRECTED, 1030 1031 [CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED, 1031 1032 [CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED, 1032 1033 [CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED,
+4
drivers/media/cec/platform/cros-ec/cros-ec-cec.c
··· 44 44 uint8_t *cec_message = cros_ec->event_data.data.cec_message; 45 45 unsigned int len = cros_ec->event_size; 46 46 47 + if (len > CEC_MAX_MSG_SIZE) 48 + len = CEC_MAX_MSG_SIZE; 47 49 cros_ec_cec->rx_msg.len = len; 48 50 memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); 49 51 ··· 223 221 { "Google", "Moli", "0000:00:02.0", "Port B" }, 224 222 /* Google Kinox */ 225 223 { "Google", "Kinox", "0000:00:02.0", "Port B" }, 224 + /* Google Kuldax */ 225 + { "Google", "Kuldax", "0000:00:02.0", "Port B" }, 226 226 }; 227 227 228 228 static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+2
drivers/media/cec/platform/s5p/s5p_cec.c
··· 115 115 dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); 116 116 cec->rx = STATE_BUSY; 117 117 cec->msg.len = status >> 24; 118 + if (cec->msg.len > CEC_MAX_MSG_SIZE) 119 + cec->msg.len = CEC_MAX_MSG_SIZE; 118 120 cec->msg.rx_status = CEC_RX_STATUS_OK; 119 121 s5p_cec_get_rx_buf(cec, cec->msg.len, 120 122 cec->msg.msg);
+1 -1
drivers/media/dvb-frontends/drxk_hard.c
··· 6660 6660 static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 6661 6661 { 6662 6662 struct drxk_state *state = fe->demodulator_priv; 6663 - u16 err; 6663 + u16 err = 0; 6664 6664 6665 6665 dprintk(1, "\n"); 6666 6666
+6 -5
drivers/media/i2c/ar0521.c
··· 406 406 struct v4l2_subdev_format *format) 407 407 { 408 408 struct ar0521_dev *sensor = to_ar0521_dev(sd); 409 - int ret = 0; 410 409 411 410 ar0521_adj_fmt(&format->format); 412 411 ··· 422 423 } 423 424 424 425 mutex_unlock(&sensor->lock); 425 - return ret; 426 + return 0; 426 427 } 427 428 428 429 static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl) ··· 755 756 gpiod_set_value(sensor->reset_gpio, 0); 756 757 usleep_range(4500, 5000); /* min 45000 clocks */ 757 758 758 - for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) 759 - if (ar0521_write_regs(sensor, initial_regs[cnt].data, 760 - initial_regs[cnt].count)) 759 + for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) { 760 + ret = ar0521_write_regs(sensor, initial_regs[cnt].data, 761 + initial_regs[cnt].count); 762 + if (ret) 761 763 goto off; 764 + } 762 765 763 766 ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT, 764 767 AR0521_REG_SERIAL_FORMAT_MIPI |
+47
drivers/media/i2c/ir-kbd-i2c.c
··· 238 238 return 1; 239 239 } 240 240 241 + static int get_key_geniatech(struct IR_i2c *ir, enum rc_proto *protocol, 242 + u32 *scancode, u8 *toggle) 243 + { 244 + int i, rc; 245 + unsigned char b; 246 + 247 + /* poll IR chip */ 248 + for (i = 0; i < 4; i++) { 249 + rc = i2c_master_recv(ir->c, &b, 1); 250 + if (rc == 1) 251 + break; 252 + msleep(20); 253 + } 254 + if (rc != 1) { 255 + dev_dbg(&ir->rc->dev, "read error\n"); 256 + if (rc < 0) 257 + return rc; 258 + return -EIO; 259 + } 260 + 261 + /* don't repeat the key */ 262 + if (ir->old == b) 263 + return 0; 264 + ir->old = b; 265 + 266 + /* decode to RC5 */ 267 + b &= 0x7f; 268 + b = (b - 1) / 2; 269 + 270 + dev_dbg(&ir->rc->dev, "key %02x\n", b); 271 + 272 + *protocol = RC_PROTO_RC5; 273 + *scancode = b; 274 + *toggle = ir->old >> 7; 275 + return 1; 276 + } 277 + 241 278 static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol, 242 279 u32 *scancode, u8 *toggle) 243 280 { ··· 803 766 rc_proto = RC_PROTO_BIT_OTHER; 804 767 ir_codes = RC_MAP_EMPTY; 805 768 break; 769 + case 0x33: 770 + name = "Geniatech"; 771 + ir->get_key = get_key_geniatech; 772 + rc_proto = RC_PROTO_BIT_RC5; 773 + ir_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02; 774 + ir->old = 0xfc; 775 + break; 806 776 case 0x6b: 807 777 name = "FusionHDTV"; 808 778 ir->get_key = get_key_fusionhdtv; ··· 868 824 break; 869 825 case IR_KBD_GET_KEY_KNC1: 870 826 ir->get_key = get_key_knc1; 827 + break; 828 + case IR_KBD_GET_KEY_GENIATECH: 829 + ir->get_key = get_key_geniatech; 871 830 break; 872 831 case IR_KBD_GET_KEY_FUSIONHDTV: 873 832 ir->get_key = get_key_fusionhdtv;
+1 -1
drivers/media/i2c/isl7998x.c
··· 8 8 9 9 #include <linux/bitfield.h> 10 10 #include <linux/delay.h> 11 - #include <linux/gpio.h> 11 + #include <linux/gpio/consumer.h> 12 12 #include <linux/i2c.h> 13 13 #include <linux/module.h> 14 14 #include <linux/of_graph.h>
+1 -1
drivers/media/i2c/mt9v111.c
··· 633 633 634 634 /* 635 635 * Set pixel integration time to the whole frame time. 636 - * This value controls the the shutter delay when running with AE 636 + * This value controls the shutter delay when running with AE 637 637 * disabled. If longer than frame time, it affects the output 638 638 * frame rate. 639 639 */
+79 -50
drivers/media/i2c/ov5640.c
··· 15 15 #include <linux/init.h> 16 16 #include <linux/module.h> 17 17 #include <linux/of_device.h> 18 + #include <linux/pm_runtime.h> 18 19 #include <linux/regulator/consumer.h> 19 20 #include <linux/slab.h> 20 21 #include <linux/types.h> ··· 447 446 448 447 /* lock to protect all members below */ 449 448 struct mutex lock; 450 - 451 - int power_count; 452 449 453 450 struct v4l2_mbus_framefmt fmt; 454 451 bool pending_fmt_change; ··· 2695 2696 return ret; 2696 2697 } 2697 2698 2698 - /* --------------- Subdev Operations --------------- */ 2699 - 2700 - static int ov5640_s_power(struct v4l2_subdev *sd, int on) 2699 + static int ov5640_sensor_suspend(struct device *dev) 2701 2700 { 2702 - struct ov5640_dev *sensor = to_ov5640_dev(sd); 2703 - int ret = 0; 2701 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 2702 + struct ov5640_dev *ov5640 = to_ov5640_dev(sd); 2704 2703 2705 - mutex_lock(&sensor->lock); 2706 - 2707 - /* 2708 - * If the power count is modified from 0 to != 0 or from != 0 to 0, 2709 - * update the power state. 2710 - */ 2711 - if (sensor->power_count == !on) { 2712 - ret = ov5640_set_power(sensor, !!on); 2713 - if (ret) 2714 - goto out; 2715 - } 2716 - 2717 - /* Update the power count. */ 2718 - sensor->power_count += on ? 1 : -1; 2719 - WARN_ON(sensor->power_count < 0); 2720 - out: 2721 - mutex_unlock(&sensor->lock); 2722 - 2723 - if (on && !ret && sensor->power_count == 1) { 2724 - /* restore controls */ 2725 - ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); 2726 - } 2727 - 2728 - return ret; 2704 + return ov5640_set_power(ov5640, false); 2729 2705 } 2706 + 2707 + static int ov5640_sensor_resume(struct device *dev) 2708 + { 2709 + struct v4l2_subdev *sd = dev_get_drvdata(dev); 2710 + struct ov5640_dev *ov5640 = to_ov5640_dev(sd); 2711 + 2712 + return ov5640_set_power(ov5640, true); 2713 + } 2714 + 2715 + /* --------------- Subdev Operations --------------- */ 2730 2716 2731 2717 static int ov5640_try_frame_interval(struct ov5640_dev *sensor, 2732 2718 struct v4l2_fract *fi, ··· 3298 3314 3299 3315 /* v4l2_ctrl_lock() locks our own mutex */ 3300 3316 3317 + if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) 3318 + return 0; 3319 + 3301 3320 switch (ctrl->id) { 3302 3321 case V4L2_CID_AUTOGAIN: 3303 3322 val = ov5640_get_gain(sensor); ··· 3315 3328 sensor->ctrls.exposure->val = val; 3316 3329 break; 3317 3330 } 3331 + 3332 + pm_runtime_put_autosuspend(&sensor->i2c_client->dev); 3318 3333 3319 3334 return 0; 3320 3335 } ··· 3347 3358 /* 3348 3359 * If the device is not powered up by the host driver do 3349 3360 * not apply any controls to H/W at this time. Instead 3350 - * the controls will be restored right after power-up. 3361 + * the controls will be restored at start streaming time. 3351 3362 */ 3352 - if (sensor->power_count == 0) 3363 + if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev)) 3353 3364 return 0; 3354 3365 3355 3366 switch (ctrl->id) { ··· 3390 3401 ret = -EINVAL; 3391 3402 break; 3392 3403 } 3404 + 3405 + pm_runtime_put_autosuspend(&sensor->i2c_client->dev); 3393 3406 3394 3407 return ret; 3395 3408 } ··· 3668 3677 struct ov5640_dev *sensor = to_ov5640_dev(sd); 3669 3678 int ret = 0; 3670 3679 3680 + if (enable) { 3681 + ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev); 3682 + if (ret < 0) 3683 + return ret; 3684 + 3685 + ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); 3686 + if (ret) { 3687 + pm_runtime_put(&sensor->i2c_client->dev); 3688 + return ret; 3689 + } 3690 + } 3691 + 3671 3692 mutex_lock(&sensor->lock); 3672 3693 3673 3694 if (sensor->streaming == !enable) { ··· 3704 3701 if (!ret) 3705 3702 sensor->streaming = enable; 3706 3703 } 3704 + 3707 3705 out: 3708 3706 mutex_unlock(&sensor->lock); 3707 + 3708 + if (!enable || ret) 3709 + pm_runtime_put_autosuspend(&sensor->i2c_client->dev); 3710 + 3709 3711 return ret; 3710 3712 } 3711 3713 ··· 3732 3724 } 3733 3725 3734 3726 static const struct v4l2_subdev_core_ops ov5640_core_ops = { 3735 - .s_power = ov5640_s_power, 3736 3727 .log_status = v4l2_ctrl_subdev_log_status, 3737 3728 .subscribe_event = v4l2_ctrl_subdev_subscribe_event, 3738 3729 .unsubscribe_event = v4l2_event_subdev_unsubscribe, ··· 3777 3770 int ret = 0; 3778 3771 u16 chip_id; 3779 3772 3780 - ret = ov5640_set_power_on(sensor); 3781 - if (ret) 3782 - return ret; 3783 - 3784 3773 ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id); 3785 3774 if (ret) { 3786 3775 dev_err(&client->dev, "%s: failed to read chip identifier\n", 3787 3776 __func__); 3788 - goto power_off; 3777 + return ret; 3789 3778 } 3790 3779 3791 3780 if (chip_id != 0x5640) { 3792 3781 dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x\n", 3793 3782 __func__, chip_id); 3794 - ret = -ENXIO; 3783 + return -ENXIO; 3795 3784 } 3796 3785 3797 - power_off: 3798 - ov5640_set_power_off(sensor); 3799 - return ret; 3786 + return 0; 3800 3787 } 3801 3788 3802 3789 static int ov5640_probe(struct i2c_client *client) ··· 3881 3880 3882 3881 ret = ov5640_get_regulators(sensor); 3883 3882 if (ret) 3884 - return ret; 3883 + goto entity_cleanup; 3885 3884 3886 3885 mutex_init(&sensor->lock); 3887 - 3888 - ret = ov5640_check_chip_id(sensor); 3889 - if (ret) 3890 - goto entity_cleanup; 3891 3886 3892 3887 ret = ov5640_init_controls(sensor); 3893 3888 if (ret) 3894 3889 goto entity_cleanup; 3895 3890 3891 + ret = ov5640_sensor_resume(dev); 3892 + if (ret) { 3893 + dev_err(dev, "failed to power on\n"); 3894 + goto entity_cleanup; 3895 + } 3896 + 3897 + pm_runtime_set_active(dev); 3898 + pm_runtime_get_noresume(dev); 3899 + pm_runtime_enable(dev); 3900 + 3901 + ret = ov5640_check_chip_id(sensor); 3902 + if (ret) 3903 + goto err_pm_runtime; 3904 + 3896 3905 ret = v4l2_async_register_subdev_sensor(&sensor->sd); 3897 3906 if (ret) 3898 - goto free_ctrls; 3907 + goto err_pm_runtime; 3908 + 3909 + pm_runtime_set_autosuspend_delay(dev, 1000); 3910 + pm_runtime_use_autosuspend(dev); 3911 + pm_runtime_put_autosuspend(dev); 3899 3912 3900 3913 return 0; 3901 3914 3902 - free_ctrls: 3915 + err_pm_runtime: 3916 + pm_runtime_put_noidle(dev); 3917 + pm_runtime_disable(dev); 3903 3918 v4l2_ctrl_handler_free(&sensor->ctrls.handler); 3919 + ov5640_sensor_suspend(dev); 3904 3920 entity_cleanup: 3905 3921 media_entity_cleanup(&sensor->sd.entity); 3906 3922 mutex_destroy(&sensor->lock); ··· 3928 3910 { 3929 3911 struct v4l2_subdev *sd = i2c_get_clientdata(client); 3930 3912 struct ov5640_dev *sensor = to_ov5640_dev(sd); 3913 + struct device *dev = &client->dev; 3914 + 3915 + pm_runtime_disable(dev); 3916 + if (!pm_runtime_status_suspended(dev)) 3917 + ov5640_sensor_suspend(dev); 3918 + pm_runtime_set_suspended(dev); 3931 3919 3932 3920 v4l2_async_unregister_subdev(&sensor->sd); 3933 3921 media_entity_cleanup(&sensor->sd.entity); 3934 3922 v4l2_ctrl_handler_free(&sensor->ctrls.handler); 3935 3923 mutex_destroy(&sensor->lock); 3936 3924 } 3925 + 3926 + static const struct dev_pm_ops ov5640_pm_ops = { 3927 + SET_RUNTIME_PM_OPS(ov5640_sensor_suspend, ov5640_sensor_resume, NULL) 3928 + }; 3937 3929 3938 3930 static const struct i2c_device_id ov5640_id[] = { 3939 3931 {"ov5640", 0}, ··· 3961 3933 .driver = { 3962 3934 .name = "ov5640", 3963 3935 .of_match_table = ov5640_dt_ids, 3936 + .pm = &ov5640_pm_ops, 3964 3937 }, 3965 3938 .id_table = ov5640_id, 3966 3939 .probe_new = ov5640_probe,
+6 -4
drivers/media/i2c/ov8865.c
··· 3034 3034 &rate); 3035 3035 if (!ret && sensor->extclk) { 3036 3036 ret = clk_set_rate(sensor->extclk, rate); 3037 - if (ret) 3038 - return dev_err_probe(dev, ret, 3039 - "failed to set clock rate\n"); 3037 + if (ret) { 3038 + dev_err_probe(dev, ret, "failed to set clock rate\n"); 3039 + goto error_endpoint; 3040 + } 3040 3041 } else if (ret && !sensor->extclk) { 3041 - return dev_err_probe(dev, ret, "invalid clock config\n"); 3042 + dev_err_probe(dev, ret, "invalid clock config\n"); 3043 + goto error_endpoint; 3042 3044 } 3043 3045 3044 3046 sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+6 -7
drivers/media/mc/mc-device.c
··· 581 581 struct media_device *mdev = entity->graph_obj.mdev; 582 582 struct media_link *link, *tmp; 583 583 struct media_interface *intf; 584 - unsigned int i; 584 + struct media_pad *iter; 585 585 586 586 ida_free(&mdev->entity_internal_idx, entity->internal_idx); 587 587 ··· 597 597 __media_entity_remove_links(entity); 598 598 599 599 /* Remove all pads that belong to this entity */ 600 - for (i = 0; i < entity->num_pads; i++) 601 - media_gobj_destroy(&entity->pads[i].graph_obj); 600 + media_entity_for_each_pad(entity, iter) 601 + media_gobj_destroy(&iter->graph_obj); 602 602 603 603 /* Remove the entity */ 604 604 media_gobj_destroy(&entity->graph_obj); ··· 610 610 struct media_entity *entity) 611 611 { 612 612 struct media_entity_notify *notify, *next; 613 - unsigned int i; 613 + struct media_pad *iter; 614 614 int ret; 615 615 616 616 if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN || ··· 639 639 media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj); 640 640 641 641 /* Initialize objects at the pads */ 642 - for (i = 0; i < entity->num_pads; i++) 643 - media_gobj_create(mdev, MEDIA_GRAPH_PAD, 644 - &entity->pads[i].graph_obj); 642 + media_entity_for_each_pad(entity, iter) 643 + media_gobj_create(mdev, MEDIA_GRAPH_PAD, &iter->graph_obj); 645 644 646 645 /* invoke entity_notify callbacks */ 647 646 list_for_each_entry_safe(notify, next, &mdev->entity_notify, list)
+544 -134
drivers/media/mc/mc-entity.c
··· 59 59 } 60 60 } 61 61 62 - __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, 63 - int idx_max) 62 + __must_check int media_entity_enum_init(struct media_entity_enum *ent_enum, 63 + struct media_device *mdev) 64 64 { 65 - idx_max = ALIGN(idx_max, BITS_PER_LONG); 65 + int idx_max; 66 + 67 + idx_max = ALIGN(mdev->entity_internal_idx_max + 1, BITS_PER_LONG); 66 68 ent_enum->bmap = bitmap_zalloc(idx_max, GFP_KERNEL); 67 69 if (!ent_enum->bmap) 68 70 return -ENOMEM; ··· 73 71 74 72 return 0; 75 73 } 76 - EXPORT_SYMBOL_GPL(__media_entity_enum_init); 74 + EXPORT_SYMBOL_GPL(media_entity_enum_init); 77 75 78 76 void media_entity_enum_cleanup(struct media_entity_enum *ent_enum) 79 77 { ··· 195 193 struct media_pad *pads) 196 194 { 197 195 struct media_device *mdev = entity->graph_obj.mdev; 198 - unsigned int i; 196 + struct media_pad *iter; 197 + unsigned int i = 0; 199 198 200 199 if (num_pads >= MEDIA_ENTITY_MAX_PADS) 201 200 return -E2BIG; ··· 207 204 if (mdev) 208 205 mutex_lock(&mdev->graph_mutex); 209 206 210 - for (i = 0; i < num_pads; i++) { 211 - pads[i].entity = entity; 212 - pads[i].index = i; 207 + media_entity_for_each_pad(entity, iter) { 208 + iter->entity = entity; 209 + iter->index = i++; 213 210 if (mdev) 214 211 media_gobj_create(mdev, MEDIA_GRAPH_PAD, 215 - &entity->pads[i].graph_obj); 212 + &iter->graph_obj); 216 213 } 217 214 218 215 if (mdev) ··· 225 222 /* ----------------------------------------------------------------------------- 226 223 * Graph traversal 227 224 */ 225 + 226 + /* 227 + * This function checks the interdependency inside the entity between @pad0 228 + * and @pad1. If two pads are interdependent they are part of the same pipeline 229 + * and enabling one of the pads means that the other pad will become "locked" 230 + * and doesn't allow configuration changes. 231 + * 232 + * This function uses the &media_entity_operations.has_pad_interdep() operation 233 + * to check the dependency inside the entity between @pad0 and @pad1. If the 234 + * has_pad_interdep operation is not implemented, all pads of the entity are 235 + * considered to be interdependent. 236 + */ 237 + static bool media_entity_has_pad_interdep(struct media_entity *entity, 238 + unsigned int pad0, unsigned int pad1) 239 + { 240 + if (pad0 >= entity->num_pads || pad1 >= entity->num_pads) 241 + return false; 242 + 243 + if (entity->pads[pad0].flags & entity->pads[pad1].flags & 244 + (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE)) 245 + return false; 246 + 247 + if (!entity->ops || !entity->ops->has_pad_interdep) 248 + return true; 249 + 250 + return entity->ops->has_pad_interdep(entity, pad0, pad1); 251 + } 228 252 229 253 static struct media_entity * 230 254 media_entity_other(struct media_entity *entity, struct media_link *link) ··· 397 367 } 398 368 EXPORT_SYMBOL_GPL(media_graph_walk_next); 399 369 400 - int media_entity_get_fwnode_pad(struct media_entity *entity, 401 - struct fwnode_handle *fwnode, 402 - unsigned long direction_flags) 403 - { 404 - struct fwnode_endpoint endpoint; 405 - unsigned int i; 406 - int ret; 407 - 408 - if (!entity->ops || !entity->ops->get_fwnode_pad) { 409 - for (i = 0; i < entity->num_pads; i++) { 410 - if (entity->pads[i].flags & direction_flags) 411 - return i; 412 - } 413 - 414 - return -ENXIO; 415 - } 416 - 417 - ret = fwnode_graph_parse_endpoint(fwnode, &endpoint); 418 - if (ret) 419 - return ret; 420 - 421 - ret = entity->ops->get_fwnode_pad(entity, &endpoint); 422 - if (ret < 0) 423 - return ret; 424 - 425 - if (ret >= entity->num_pads) 426 - return -ENXIO; 427 - 428 - if (!(entity->pads[ret].flags & direction_flags)) 429 - return -ENXIO; 430 - 431 - return ret; 432 - } 433 - EXPORT_SYMBOL_GPL(media_entity_get_fwnode_pad); 434 - 435 370 /* ----------------------------------------------------------------------------- 436 371 * Pipeline management 437 372 */ 438 373 439 - __must_check int __media_pipeline_start(struct media_entity *entity, 440 - struct media_pipeline *pipe) 374 + /* 375 + * The pipeline traversal stack stores pads that are reached during graph 376 + * traversal, with a list of links to be visited to continue the traversal. 377 + * When a new pad is reached, an entry is pushed on the top of the stack and 378 + * points to the incoming pad and the first link of the entity. 379 + * 380 + * To find further pads in the pipeline, the traversal algorithm follows 381 + * internal pad dependencies in the entity, and then links in the graph. It 382 + * does so by iterating over all links of the entity, and following enabled 383 + * links that originate from a pad that is internally connected to the incoming 384 + * pad, as reported by the media_entity_has_pad_interdep() function. 385 + */ 386 + 387 + /** 388 + * struct media_pipeline_walk_entry - Entry in the pipeline traversal stack 389 + * 390 + * @pad: The media pad being visited 391 + * @links: Links left to be visited 392 + */ 393 + struct media_pipeline_walk_entry { 394 + struct media_pad *pad; 395 + struct list_head *links; 396 + }; 397 + 398 + /** 399 + * struct media_pipeline_walk - State used by the media pipeline traversal 400 + * algorithm 401 + * 402 + * @mdev: The media device 403 + * @stack: Depth-first search stack 404 + * @stack.size: Number of allocated entries in @stack.entries 405 + * @stack.top: Index of the top stack entry (-1 if the stack is empty) 406 + * @stack.entries: Stack entries 407 + */ 408 + struct media_pipeline_walk { 409 + struct media_device *mdev; 410 + 411 + struct { 412 + unsigned int size; 413 + int top; 414 + struct media_pipeline_walk_entry *entries; 415 + } stack; 416 + }; 417 + 418 + #define MEDIA_PIPELINE_STACK_GROW_STEP 16 419 + 420 + static struct media_pipeline_walk_entry * 421 + media_pipeline_walk_top(struct media_pipeline_walk *walk) 441 422 { 442 - struct media_device *mdev = entity->graph_obj.mdev; 443 - struct media_graph *graph = &pipe->graph; 444 - struct media_entity *entity_err = entity; 445 - struct media_link *link; 423 + return &walk->stack.entries[walk->stack.top]; 424 + } 425 + 426 + static bool media_pipeline_walk_empty(struct media_pipeline_walk *walk) 427 + { 428 + return walk->stack.top == -1; 429 + } 430 + 431 + /* Increase the stack size by MEDIA_PIPELINE_STACK_GROW_STEP elements. */ 432 + static int media_pipeline_walk_resize(struct media_pipeline_walk *walk) 433 + { 434 + struct media_pipeline_walk_entry *entries; 435 + unsigned int new_size; 436 + 437 + /* Safety check, to avoid stack overflows in case of bugs. */ 438 + if (walk->stack.size >= 256) 439 + return -E2BIG; 440 + 441 + new_size = walk->stack.size + MEDIA_PIPELINE_STACK_GROW_STEP; 442 + 443 + entries = krealloc(walk->stack.entries, 444 + new_size * sizeof(*walk->stack.entries), 445 + GFP_KERNEL); 446 + if (!entries) 447 + return -ENOMEM; 448 + 449 + walk->stack.entries = entries; 450 + walk->stack.size = new_size; 451 + 452 + return 0; 453 + } 454 + 455 + /* Push a new entry on the stack. */ 456 + static int media_pipeline_walk_push(struct media_pipeline_walk *walk, 457 + struct media_pad *pad) 458 + { 459 + struct media_pipeline_walk_entry *entry; 446 460 int ret; 447 461 448 - if (pipe->streaming_count) { 449 - pipe->streaming_count++; 462 + if (walk->stack.top + 1 >= walk->stack.size) { 463 + ret = media_pipeline_walk_resize(walk); 464 + if (ret) 465 + return ret; 466 + } 467 + 468 + walk->stack.top++; 469 + entry = media_pipeline_walk_top(walk); 470 + entry->pad = pad; 471 + entry->links = pad->entity->links.next; 472 + 473 + dev_dbg(walk->mdev->dev, 474 + "media pipeline: pushed entry %u: '%s':%u\n", 475 + walk->stack.top, pad->entity->name, pad->index); 476 + 477 + return 0; 478 + } 479 + 480 + /* 481 + * Move the top entry link cursor to the next link. If all links of the entry 482 + * have been visited, pop the entry itself. 483 + */ 484 + static void media_pipeline_walk_pop(struct media_pipeline_walk *walk) 485 + { 486 + struct media_pipeline_walk_entry *entry; 487 + 488 + if (WARN_ON(walk->stack.top < 0)) 489 + return; 490 + 491 + entry = media_pipeline_walk_top(walk); 492 + 493 + if (entry->links->next == &entry->pad->entity->links) { 494 + dev_dbg(walk->mdev->dev, 495 + "media pipeline: entry %u has no more links, popping\n", 496 + walk->stack.top); 497 + 498 + walk->stack.top--; 499 + return; 500 + } 501 + 502 + entry->links = entry->links->next; 503 + 504 + dev_dbg(walk->mdev->dev, 505 + "media pipeline: moved entry %u to next link\n", 506 + walk->stack.top); 507 + } 508 + 509 + /* Free all memory allocated while walking the pipeline. */ 510 + static void media_pipeline_walk_destroy(struct media_pipeline_walk *walk) 511 + { 512 + kfree(walk->stack.entries); 513 + } 514 + 515 + /* Add a pad to the pipeline and push it to the stack. */ 516 + static int media_pipeline_add_pad(struct media_pipeline *pipe, 517 + struct media_pipeline_walk *walk, 518 + struct media_pad *pad) 519 + { 520 + struct media_pipeline_pad *ppad; 521 + 522 + list_for_each_entry(ppad, &pipe->pads, list) { 523 + if (ppad->pad == pad) { 524 + dev_dbg(pad->graph_obj.mdev->dev, 525 + "media pipeline: already contains pad '%s':%u\n", 526 + pad->entity->name, pad->index); 527 + return 0; 528 + } 529 + } 530 + 531 + ppad = kzalloc(sizeof(*ppad), GFP_KERNEL); 532 + if (!ppad) 533 + return -ENOMEM; 534 + 535 + ppad->pipe = pipe; 536 + ppad->pad = pad; 537 + 538 + list_add_tail(&ppad->list, &pipe->pads); 539 + 540 + dev_dbg(pad->graph_obj.mdev->dev, 541 + "media pipeline: added pad '%s':%u\n", 542 + pad->entity->name, pad->index); 543 + 544 + return media_pipeline_walk_push(walk, pad); 545 + } 546 + 547 + /* Explore the next link of the entity at the top of the stack. */ 548 + static int media_pipeline_explore_next_link(struct media_pipeline *pipe, 549 + struct media_pipeline_walk *walk) 550 + { 551 + struct media_pipeline_walk_entry *entry = media_pipeline_walk_top(walk); 552 + struct media_pad *pad; 553 + struct media_link *link; 554 + struct media_pad *local; 555 + struct media_pad *remote; 556 + int ret; 557 + 558 + pad = entry->pad; 559 + link = list_entry(entry->links, typeof(*link), list); 560 + media_pipeline_walk_pop(walk); 561 + 562 + dev_dbg(walk->mdev->dev, 563 + "media pipeline: exploring link '%s':%u -> '%s':%u\n", 564 + link->source->entity->name, link->source->index, 565 + link->sink->entity->name, link->sink->index); 566 + 567 + /* Skip links that are not enabled. */ 568 + if (!(link->flags & MEDIA_LNK_FL_ENABLED)) { 569 + dev_dbg(walk->mdev->dev, 570 + "media pipeline: skipping link (disabled)\n"); 450 571 return 0; 451 572 } 452 573 453 - ret = media_graph_walk_init(&pipe->graph, mdev); 574 + /* Get the local pad and remote pad. */ 575 + if (link->source->entity == pad->entity) { 576 + local = link->source; 577 + remote = link->sink; 578 + } else { 579 + local = link->sink; 580 + remote = link->source; 581 + } 582 + 583 + /* 584 + * Skip links that originate from a different pad than the incoming pad 585 + * that is not connected internally in the entity to the incoming pad. 586 + */ 587 + if (pad != local && 588 + !media_entity_has_pad_interdep(pad->entity, pad->index, local->index)) { 589 + dev_dbg(walk->mdev->dev, 590 + "media pipeline: skipping link (no route)\n"); 591 + return 0; 592 + } 593 + 594 + /* 595 + * Add the local and remote pads of the link to the pipeline and push 596 + * them to the stack, if they're not already present. 597 + */ 598 + ret = media_pipeline_add_pad(pipe, walk, local); 454 599 if (ret) 455 600 return ret; 456 601 457 - media_graph_walk_start(&pipe->graph, entity); 602 + ret = media_pipeline_add_pad(pipe, walk, remote); 603 + if (ret) 604 + return ret; 458 605 459 - while ((entity = media_graph_walk_next(graph))) { 460 - DECLARE_BITMAP(active, MEDIA_ENTITY_MAX_PADS); 461 - DECLARE_BITMAP(has_no_links, MEDIA_ENTITY_MAX_PADS); 606 + return 0; 607 + } 462 608 463 - if (entity->pipe && entity->pipe != pipe) { 464 - pr_err("Pipe active for %s. Can't start for %s\n", 465 - entity->name, 466 - entity_err->name); 609 + static void media_pipeline_cleanup(struct media_pipeline *pipe) 610 + { 611 + while (!list_empty(&pipe->pads)) { 612 + struct media_pipeline_pad *ppad; 613 + 614 + ppad = list_first_entry(&pipe->pads, typeof(*ppad), list); 615 + list_del(&ppad->list); 616 + kfree(ppad); 617 + } 618 + } 619 + 620 + static int media_pipeline_populate(struct media_pipeline *pipe, 621 + struct media_pad *pad) 622 + { 623 + struct media_pipeline_walk walk = { }; 624 + struct media_pipeline_pad *ppad; 625 + int ret; 626 + 627 + /* 628 + * Populate the media pipeline by walking the media graph, starting 629 + * from @pad. 630 + */ 631 + INIT_LIST_HEAD(&pipe->pads); 632 + pipe->mdev = pad->graph_obj.mdev; 633 + 634 + walk.mdev = pipe->mdev; 635 + walk.stack.top = -1; 636 + ret = media_pipeline_add_pad(pipe, &walk, pad); 637 + if (ret) 638 + goto done; 639 + 640 + /* 641 + * Use a depth-first search algorithm: as long as the stack is not 642 + * empty, explore the next link of the top entry. The 643 + * media_pipeline_explore_next_link() function will either move to the 644 + * next link, pop the entry if fully visited, or add new entries on 645 + * top. 646 + */ 647 + while (!media_pipeline_walk_empty(&walk)) { 648 + ret = media_pipeline_explore_next_link(pipe, &walk); 649 + if (ret) 650 + goto done; 651 + } 652 + 653 + dev_dbg(pad->graph_obj.mdev->dev, 654 + "media pipeline populated, found pads:\n"); 655 + 656 + list_for_each_entry(ppad, &pipe->pads, list) 657 + dev_dbg(pad->graph_obj.mdev->dev, "- '%s':%u\n", 658 + ppad->pad->entity->name, ppad->pad->index); 659 + 660 + WARN_ON(walk.stack.top != -1); 661 + 662 + ret = 0; 663 + 664 + done: 665 + media_pipeline_walk_destroy(&walk); 666 + 667 + if (ret) 668 + media_pipeline_cleanup(pipe); 669 + 670 + return ret; 671 + } 672 + 673 + __must_check int __media_pipeline_start(struct media_pad *pad, 674 + struct media_pipeline *pipe) 675 + { 676 + struct media_device *mdev = pad->entity->graph_obj.mdev; 677 + struct media_pipeline_pad *err_ppad; 678 + struct media_pipeline_pad *ppad; 679 + int ret; 680 + 681 + lockdep_assert_held(&mdev->graph_mutex); 682 + 683 + /* 684 + * If the entity is already part of a pipeline, that pipeline must 685 + * be the same as the pipe given to media_pipeline_start(). 686 + */ 687 + if (WARN_ON(pad->pipe && pad->pipe != pipe)) 688 + return -EINVAL; 689 + 690 + /* 691 + * If the pipeline has already been started, it is guaranteed to be 692 + * valid, so just increase the start count. 693 + */ 694 + if (pipe->start_count) { 695 + pipe->start_count++; 696 + return 0; 697 + } 698 + 699 + /* 700 + * Populate the pipeline. This populates the media_pipeline pads list 701 + * with media_pipeline_pad instances for each pad found during graph 702 + * walk. 703 + */ 704 + ret = media_pipeline_populate(pipe, pad); 705 + if (ret) 706 + return ret; 707 + 708 + /* 709 + * Now that all the pads in the pipeline have been gathered, perform 710 + * the validation steps. 711 + */ 712 + 713 + list_for_each_entry(ppad, &pipe->pads, list) { 714 + struct media_pad *pad = ppad->pad; 715 + struct media_entity *entity = pad->entity; 716 + bool has_enabled_link = false; 717 + bool has_link = false; 718 + struct media_link *link; 719 + 720 + dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name, 721 + pad->index); 722 + 723 + /* 724 + * 1. Ensure that the pad doesn't already belong to a different 725 + * pipeline. 726 + */ 727 + if (pad->pipe) { 728 + dev_dbg(mdev->dev, "Failed to start pipeline: pad '%s':%u busy\n", 729 + pad->entity->name, pad->index); 467 730 ret = -EBUSY; 468 731 goto error; 469 732 } 470 733 471 - /* Already streaming --- no need to check. */ 472 - if (entity->pipe) 473 - continue; 474 - 475 - entity->pipe = pipe; 476 - 477 - if (!entity->ops || !entity->ops->link_validate) 478 - continue; 479 - 480 - bitmap_zero(active, entity->num_pads); 481 - bitmap_fill(has_no_links, entity->num_pads); 482 - 734 + /* 735 + * 2. Validate all active links whose sink is the current pad. 736 + * Validation of the source pads is performed in the context of 737 + * the connected sink pad to avoid duplicating checks. 738 + */ 483 739 for_each_media_entity_data_link(entity, link) { 484 - struct media_pad *pad = link->sink->entity == entity 485 - ? link->sink : link->source; 740 + /* Skip links unrelated to the current pad. */ 741 + if (link->sink != pad && link->source != pad) 742 + continue; 486 743 487 - /* Mark that a pad is connected by a link. */ 488 - bitmap_clear(has_no_links, pad->index, 1); 489 - 490 - /* 491 - * Pads that either do not need to connect or 492 - * are connected through an enabled link are 493 - * fine. 494 - */ 495 - if (!(pad->flags & MEDIA_PAD_FL_MUST_CONNECT) || 496 - link->flags & MEDIA_LNK_FL_ENABLED) 497 - bitmap_set(active, pad->index, 1); 744 + /* Record if the pad has links and enabled links. */ 745 + if (link->flags & MEDIA_LNK_FL_ENABLED) 746 + has_enabled_link = true; 747 + has_link = true; 498 748 499 749 /* 500 - * Link validation will only take place for 501 - * sink ends of the link that are enabled. 750 + * Validate the link if it's enabled and has the 751 + * current pad as its sink. 502 752 */ 503 - if (link->sink != pad || 504 - !(link->flags & MEDIA_LNK_FL_ENABLED)) 753 + if (!(link->flags & MEDIA_LNK_FL_ENABLED)) 754 + continue; 755 + 756 + if (link->sink != pad) 757 + continue; 758 + 759 + if (!entity->ops || !entity->ops->link_validate) 505 760 continue; 506 761 507 762 ret = entity->ops->link_validate(link); 508 - if (ret < 0 && ret != -ENOIOCTLCMD) { 509 - dev_dbg(entity->graph_obj.mdev->dev, 510 - "link validation failed for '%s':%u -> '%s':%u, error %d\n", 763 + if (ret) { 764 + dev_dbg(mdev->dev, 765 + "Link '%s':%u -> '%s':%u failed validation: %d\n", 511 766 link->source->entity->name, 512 767 link->source->index, 513 - entity->name, link->sink->index, ret); 768 + link->sink->entity->name, 769 + link->sink->index, ret); 514 770 goto error; 515 771 } 772 + 773 + dev_dbg(mdev->dev, 774 + "Link '%s':%u -> '%s':%u is valid\n", 775 + link->source->entity->name, 776 + link->source->index, 777 + link->sink->entity->name, 778 + link->sink->index); 516 779 } 517 780 518 - /* Either no links or validated links are fine. */ 519 - bitmap_or(active, active, has_no_links, entity->num_pads); 520 - 521 - if (!bitmap_full(active, entity->num_pads)) { 781 + /* 782 + * 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set, 783 + * ensure that it has either no link or an enabled link. 784 + */ 785 + if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link && 786 + !has_enabled_link) { 787 + dev_dbg(mdev->dev, 788 + "Pad '%s':%u must be connected by an enabled link\n", 789 + pad->entity->name, pad->index); 522 790 ret = -ENOLINK; 523 - dev_dbg(entity->graph_obj.mdev->dev, 524 - "'%s':%u must be connected by an enabled link\n", 525 - entity->name, 526 - (unsigned)find_first_zero_bit( 527 - active, entity->num_pads)); 528 791 goto error; 529 792 } 793 + 794 + /* Validation passed, store the pipe pointer in the pad. */ 795 + pad->pipe = pipe; 530 796 } 531 797 532 - pipe->streaming_count++; 798 + pipe->start_count++; 533 799 534 800 return 0; 535 801 ··· 834 508 * Link validation on graph failed. We revert what we did and 835 509 * return the error. 836 510 */ 837 - media_graph_walk_start(graph, entity_err); 838 511 839 - while ((entity_err = media_graph_walk_next(graph))) { 840 - entity_err->pipe = NULL; 841 - 842 - /* 843 - * We haven't started entities further than this so we quit 844 - * here. 845 - */ 846 - if (entity_err == entity) 512 + list_for_each_entry(err_ppad, &pipe->pads, list) { 513 + if (err_ppad == ppad) 847 514 break; 515 + 516 + err_ppad->pad->pipe = NULL; 848 517 } 849 518 850 - media_graph_walk_cleanup(graph); 519 + media_pipeline_cleanup(pipe); 851 520 852 521 return ret; 853 522 } 854 523 EXPORT_SYMBOL_GPL(__media_pipeline_start); 855 524 856 - __must_check int media_pipeline_start(struct media_entity *entity, 525 + __must_check int media_pipeline_start(struct media_pad *pad, 857 526 struct media_pipeline *pipe) 858 527 { 859 - struct media_device *mdev = entity->graph_obj.mdev; 528 + struct media_device *mdev = pad->entity->graph_obj.mdev; 860 529 int ret; 861 530 862 531 mutex_lock(&mdev->graph_mutex); 863 - ret = __media_pipeline_start(entity, pipe); 532 + ret = __media_pipeline_start(pad, pipe); 864 533 mutex_unlock(&mdev->graph_mutex); 865 534 return ret; 866 535 } 867 536 EXPORT_SYMBOL_GPL(media_pipeline_start); 868 537 869 - void __media_pipeline_stop(struct media_entity *entity) 538 + void __media_pipeline_stop(struct media_pad *pad) 870 539 { 871 - struct media_graph *graph = &entity->pipe->graph; 872 - struct media_pipeline *pipe = entity->pipe; 540 + struct media_pipeline *pipe = pad->pipe; 541 + struct media_pipeline_pad *ppad; 873 542 874 543 /* 875 544 * If the following check fails, the driver has performed an ··· 873 552 if (WARN_ON(!pipe)) 874 553 return; 875 554 876 - if (--pipe->streaming_count) 555 + if (--pipe->start_count) 877 556 return; 878 557 879 - media_graph_walk_start(graph, entity); 558 + list_for_each_entry(ppad, &pipe->pads, list) 559 + ppad->pad->pipe = NULL; 880 560 881 - while ((entity = media_graph_walk_next(graph))) 882 - entity->pipe = NULL; 561 + media_pipeline_cleanup(pipe); 883 562 884 - media_graph_walk_cleanup(graph); 885 - 563 + if (pipe->allocated) 564 + kfree(pipe); 886 565 } 887 566 EXPORT_SYMBOL_GPL(__media_pipeline_stop); 888 567 889 - void media_pipeline_stop(struct media_entity *entity) 568 + void media_pipeline_stop(struct media_pad *pad) 890 569 { 891 - struct media_device *mdev = entity->graph_obj.mdev; 570 + struct media_device *mdev = pad->entity->graph_obj.mdev; 892 571 893 572 mutex_lock(&mdev->graph_mutex); 894 - __media_pipeline_stop(entity); 573 + __media_pipeline_stop(pad); 895 574 mutex_unlock(&mdev->graph_mutex); 896 575 } 897 576 EXPORT_SYMBOL_GPL(media_pipeline_stop); 577 + 578 + __must_check int media_pipeline_alloc_start(struct media_pad *pad) 579 + { 580 + struct media_device *mdev = pad->entity->graph_obj.mdev; 581 + struct media_pipeline *new_pipe = NULL; 582 + struct media_pipeline *pipe; 583 + int ret; 584 + 585 + mutex_lock(&mdev->graph_mutex); 586 + 587 + /* 588 + * Is the entity already part of a pipeline? If not, we need to allocate 589 + * a pipe. 590 + */ 591 + pipe = media_pad_pipeline(pad); 592 + if (!pipe) { 593 + new_pipe = kzalloc(sizeof(*new_pipe), GFP_KERNEL); 594 + if (!new_pipe) { 595 + ret = -ENOMEM; 596 + goto out; 597 + } 598 + 599 + pipe = new_pipe; 600 + pipe->allocated = true; 601 + } 602 + 603 + ret = __media_pipeline_start(pad, pipe); 604 + if (ret) 605 + kfree(new_pipe); 606 + 607 + out: 608 + mutex_unlock(&mdev->graph_mutex); 609 + 610 + return ret; 611 + } 612 + EXPORT_SYMBOL_GPL(media_pipeline_alloc_start); 898 613 899 614 /* ----------------------------------------------------------------------------- 900 615 * Links management ··· 1186 829 { 1187 830 const u32 mask = MEDIA_LNK_FL_ENABLED; 1188 831 struct media_device *mdev; 1189 - struct media_entity *source, *sink; 832 + struct media_pad *source, *sink; 1190 833 int ret = -EBUSY; 1191 834 1192 835 if (link == NULL) ··· 1202 845 if (link->flags == flags) 1203 846 return 0; 1204 847 1205 - source = link->source->entity; 1206 - sink = link->sink->entity; 848 + source = link->source; 849 + sink = link->sink; 1207 850 1208 851 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) && 1209 - (media_entity_is_streaming(source) || 1210 - media_entity_is_streaming(sink))) 852 + (media_pad_is_streaming(source) || media_pad_is_streaming(sink))) 1211 853 return -EBUSY; 1212 854 1213 855 mdev = source->graph_obj.mdev; ··· 1346 990 return found_pad; 1347 991 } 1348 992 EXPORT_SYMBOL_GPL(media_pad_remote_pad_unique); 993 + 994 + int media_entity_get_fwnode_pad(struct media_entity *entity, 995 + struct fwnode_handle *fwnode, 996 + unsigned long direction_flags) 997 + { 998 + struct fwnode_endpoint endpoint; 999 + unsigned int i; 1000 + int ret; 1001 + 1002 + if (!entity->ops || !entity->ops->get_fwnode_pad) { 1003 + for (i = 0; i < entity->num_pads; i++) { 1004 + if (entity->pads[i].flags & direction_flags) 1005 + return i; 1006 + } 1007 + 1008 + return -ENXIO; 1009 + } 1010 + 1011 + ret = fwnode_graph_parse_endpoint(fwnode, &endpoint); 1012 + if (ret) 1013 + return ret; 1014 + 1015 + ret = entity->ops->get_fwnode_pad(entity, &endpoint); 1016 + if (ret < 0) 1017 + return ret; 1018 + 1019 + if (ret >= entity->num_pads) 1020 + return -ENXIO; 1021 + 1022 + if (!(entity->pads[ret].flags & direction_flags)) 1023 + return -ENXIO; 1024 + 1025 + return ret; 1026 + } 1027 + EXPORT_SYMBOL_GPL(media_entity_get_fwnode_pad); 1028 + 1029 + struct media_pipeline *media_entity_pipeline(struct media_entity *entity) 1030 + { 1031 + struct media_pad *pad; 1032 + 1033 + media_entity_for_each_pad(entity, pad) { 1034 + if (pad->pipe) 1035 + return pad->pipe; 1036 + } 1037 + 1038 + return NULL; 1039 + } 1040 + EXPORT_SYMBOL_GPL(media_entity_pipeline); 1041 + 1042 + struct media_pipeline *media_pad_pipeline(struct media_pad *pad) 1043 + { 1044 + return pad->pipe; 1045 + } 1046 + EXPORT_SYMBOL_GPL(media_pad_pipeline); 1349 1047 1350 1048 static void media_interface_init(struct media_device *mdev, 1351 1049 struct media_interface *intf,
+2 -2
drivers/media/pci/cx18/cx18-av-core.c
··· 339 339 340 340 /* 341 341 * For a 13.5 Mpps clock and 15,625 Hz line rate, a line is 342 - * is 864 pixels = 720 active + 144 blanking. ITU-R BT.601 342 + * 864 pixels = 720 active + 144 blanking. ITU-R BT.601 343 343 * specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after 344 344 * the end of active video to start a horizontal line, so that 345 345 * leaves 132 pixels of hblank to ignore. ··· 399 399 400 400 /* 401 401 * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is 402 - * is 858 pixels = 720 active + 138 blanking. The Hsync leading 402 + * 858 pixels = 720 active + 138 blanking. The Hsync leading 403 403 * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the 404 404 * end of active video, leaving 122 pixels of hblank to ignore 405 405 * before active video starts.
+1 -1
drivers/media/pci/cx88/cx88-input.c
··· 586 586 { 587 587 struct i2c_board_info info; 588 588 static const unsigned short default_addr_list[] = { 589 - 0x18, 0x6b, 0x71, 589 + 0x18, 0x33, 0x6b, 0x71, 590 590 I2C_CLIENT_END 591 591 }; 592 592 static const unsigned short pvr2000_addr_list[] = {
+1
drivers/media/pci/cx88/cx88-video.c
··· 1388 1388 } 1389 1389 fallthrough; 1390 1390 case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: 1391 + case CX88_BOARD_NOTONLYTV_LV3H: 1391 1392 request_module("ir-kbd-i2c"); 1392 1393 } 1393 1394
+3 -3
drivers/media/pci/intel/ipu3/ipu3-cio2-main.c
··· 989 989 return r; 990 990 } 991 991 992 - r = media_pipeline_start(&q->vdev.entity, &q->pipe); 992 + r = video_device_pipeline_start(&q->vdev, &q->pipe); 993 993 if (r) 994 994 goto fail_pipeline; 995 995 ··· 1009 1009 fail_csi2_subdev: 1010 1010 cio2_hw_exit(cio2, q); 1011 1011 fail_hw: 1012 - media_pipeline_stop(&q->vdev.entity); 1012 + video_device_pipeline_stop(&q->vdev); 1013 1013 fail_pipeline: 1014 1014 dev_dbg(dev, "failed to start streaming (%d)\n", r); 1015 1015 cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_QUEUED); ··· 1030 1030 cio2_hw_exit(cio2, q); 1031 1031 synchronize_irq(cio2->pci_dev->irq); 1032 1032 cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR); 1033 - media_pipeline_stop(&q->vdev.entity); 1033 + video_device_pipeline_stop(&q->vdev); 1034 1034 pm_runtime_put(dev); 1035 1035 cio2->streaming = false; 1036 1036 }
+4 -7
drivers/media/platform/amphion/vpu_v4l2.c
··· 603 603 inst->workqueue = NULL; 604 604 } 605 605 606 + if (inst->fh.m2m_ctx) { 607 + v4l2_m2m_ctx_release(inst->fh.m2m_ctx); 608 + inst->fh.m2m_ctx = NULL; 609 + } 606 610 v4l2_ctrl_handler_free(&inst->ctrl_handler); 607 611 mutex_destroy(&inst->lock); 608 612 v4l2_fh_del(&inst->fh); ··· 688 684 struct vpu_inst *inst = to_inst(file); 689 685 690 686 vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst); 691 - 692 - vpu_inst_lock(inst); 693 - if (inst->fh.m2m_ctx) { 694 - v4l2_m2m_ctx_release(inst->fh.m2m_ctx); 695 - inst->fh.m2m_ctx = NULL; 696 - } 697 - vpu_inst_unlock(inst); 698 687 699 688 call_void_vop(inst, release); 700 689 vpu_inst_unregister(inst);
+3 -10
drivers/media/platform/chips-media/coda-jpeg.c
··· 421 421 coda_write(dev, (s32)values[i], CODA9_REG_JPEG_HUFF_DATA); 422 422 } 423 423 424 - static int coda9_jpeg_dec_huff_setup(struct coda_ctx *ctx) 424 + static void coda9_jpeg_dec_huff_setup(struct coda_ctx *ctx) 425 425 { 426 426 struct coda_huff_tab *huff_tab = ctx->params.jpeg_huff_tab; 427 427 struct coda_dev *dev = ctx->dev; ··· 455 455 coda9_jpeg_write_huff_values(dev, huff_tab->luma_ac, 162); 456 456 coda9_jpeg_write_huff_values(dev, huff_tab->chroma_ac, 162); 457 457 coda_write(dev, 0x000, CODA9_REG_JPEG_HUFF_CTRL); 458 - return 0; 459 458 } 460 459 461 460 static inline void coda9_jpeg_write_qmat_tab(struct coda_dev *dev, ··· 1393 1394 coda_write(dev, ctx->params.jpeg_restart_interval, 1394 1395 CODA9_REG_JPEG_RST_INTVAL); 1395 1396 1396 - if (ctx->params.jpeg_huff_tab) { 1397 - ret = coda9_jpeg_dec_huff_setup(ctx); 1398 - if (ret < 0) { 1399 - v4l2_err(&dev->v4l2_dev, 1400 - "failed to set up Huffman tables: %d\n", ret); 1401 - return ret; 1402 - } 1403 - } 1397 + if (ctx->params.jpeg_huff_tab) 1398 + coda9_jpeg_dec_huff_setup(ctx); 1404 1399 1405 1400 coda9_jpeg_qmat_setup(ctx); 1406 1401
+1 -1
drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c
··· 457 457 kfree(path); 458 458 atomic_dec(&mdp->job_count); 459 459 wake_up(&mdp->callback_wq); 460 - if (cmd->pkt.buf_size > 0) 460 + if (cmd && cmd->pkt.buf_size > 0) 461 461 mdp_cmdq_pkt_destroy(&cmd->pkt); 462 462 kfree(comps); 463 463 kfree(cmd);
+4 -3
drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c
··· 682 682 int i, ret; 683 683 684 684 if (comp->comp_dev) { 685 - ret = pm_runtime_get_sync(comp->comp_dev); 685 + ret = pm_runtime_resume_and_get(comp->comp_dev); 686 686 if (ret < 0) { 687 687 dev_err(dev, 688 688 "Failed to get power, err %d. type:%d id:%d\n", ··· 699 699 dev_err(dev, 700 700 "Failed to enable clk %d. type:%d id:%d\n", 701 701 i, comp->type, comp->id); 702 + pm_runtime_put(comp->comp_dev); 702 703 return ret; 703 704 } 704 705 } ··· 870 869 871 870 ret = mdp_comp_init(mdp, node, comp, id); 872 871 if (ret) { 873 - kfree(comp); 872 + devm_kfree(dev, comp); 874 873 return ERR_PTR(ret); 875 874 } 876 875 mdp->comp[id] = comp; ··· 931 930 if (mdp->comp[i]) { 932 931 pm_runtime_disable(mdp->comp[i]->comp_dev); 933 932 mdp_comp_deinit(mdp->comp[i]); 934 - kfree(mdp->comp[i]); 933 + devm_kfree(mdp->comp[i]->comp_dev, mdp->comp[i]); 935 934 mdp->comp[i] = NULL; 936 935 } 937 936 }
+2 -1
drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c
··· 289 289 mdp_comp_destroy(mdp); 290 290 err_return: 291 291 for (i = 0; i < MDP_PIPE_MAX; i++) 292 - mtk_mutex_put(mdp->mdp_mutex[i]); 292 + if (mdp) 293 + mtk_mutex_put(mdp->mdp_mutex[i]); 293 294 kfree(mdp); 294 295 dev_dbg(dev, "Errno %d\n", ret); 295 296 return ret;
+2 -1
drivers/media/platform/mediatek/mdp3/mtk-mdp3-vpu.c
··· 173 173 /* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */ 174 174 175 175 mem_size = vpu_alloc_size; 176 - if (mdp_vpu_shared_mem_alloc(vpu)) { 176 + err = mdp_vpu_shared_mem_alloc(vpu); 177 + if (err) { 177 178 dev_err(&mdp->pdev->dev, "VPU memory alloc fail!"); 178 179 goto err_mem_alloc; 179 180 }
+2 -2
drivers/media/platform/nxp/dw100/dw100.c
··· 373 373 * The coordinates are saved in UQ12.4 fixed point format. 374 374 */ 375 375 static void dw100_ctrl_dewarping_map_init(const struct v4l2_ctrl *ctrl, 376 - u32 from_idx, u32 elems, 376 + u32 from_idx, 377 377 union v4l2_ctrl_ptr ptr) 378 378 { 379 379 struct dw100_ctx *ctx = ··· 398 398 ctx->map_height = mh; 399 399 ctx->map_size = mh * mw * sizeof(u32); 400 400 401 - for (idx = from_idx; idx < elems; idx++) { 401 + for (idx = from_idx; idx < ctrl->elems; idx++) { 402 402 qy = min_t(u32, (idx / mw) * qdy, qsh); 403 403 qx = min_t(u32, (idx % mw) * qdx, qsw); 404 404 map[idx] = dw100_map_format_coordinates(qx, qy);
+3 -3
drivers/media/platform/qcom/camss/camss-video.c
··· 493 493 struct v4l2_subdev *subdev; 494 494 int ret; 495 495 496 - ret = media_pipeline_start(&vdev->entity, &video->pipe); 496 + ret = video_device_pipeline_start(vdev, &video->pipe); 497 497 if (ret < 0) 498 498 return ret; 499 499 ··· 522 522 return 0; 523 523 524 524 error: 525 - media_pipeline_stop(&vdev->entity); 525 + video_device_pipeline_stop(vdev); 526 526 527 527 video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED); 528 528 ··· 553 553 v4l2_subdev_call(subdev, video, s_stream, 0); 554 554 } 555 555 556 - media_pipeline_stop(&vdev->entity); 556 + video_device_pipeline_stop(vdev); 557 557 558 558 video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR); 559 559 }
+7 -6
drivers/media/platform/qcom/venus/helpers.c
··· 1800 1800 struct venus_core *core = inst->core; 1801 1801 u32 fmt = to_hfi_raw_fmt(v4l2_pixfmt); 1802 1802 struct hfi_plat_caps *caps; 1803 - u32 buftype; 1803 + bool found; 1804 1804 1805 1805 if (!fmt) 1806 1806 return false; ··· 1809 1809 if (!caps) 1810 1810 return false; 1811 1811 1812 - if (inst->session_type == VIDC_SESSION_TYPE_DEC) 1813 - buftype = HFI_BUFFER_OUTPUT2; 1814 - else 1815 - buftype = HFI_BUFFER_OUTPUT; 1812 + found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt); 1813 + if (found) 1814 + goto done; 1816 1815 1817 - return find_fmt_from_caps(caps, buftype, fmt); 1816 + found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt); 1817 + done: 1818 + return found; 1818 1819 } 1819 1820 EXPORT_SYMBOL_GPL(venus_helper_check_format); 1820 1821
+1 -4
drivers/media/platform/qcom/venus/hfi.c
··· 569 569 570 570 int hfi_create(struct venus_core *core, const struct hfi_core_ops *ops) 571 571 { 572 - int ret; 573 - 574 572 if (!ops) 575 573 return -EINVAL; 576 574 ··· 577 579 core->state = CORE_UNINIT; 578 580 init_completion(&core->done); 579 581 pkt_set_version(core->res->hfi_version); 580 - ret = venus_hfi_create(core); 581 582 582 - return ret; 583 + return venus_hfi_create(core); 583 584 } 584 585 585 586 void hfi_destroy(struct venus_core *core)
+2
drivers/media/platform/qcom/venus/vdec.c
··· 183 183 else 184 184 return NULL; 185 185 fmt = find_format(inst, pixmp->pixelformat, f->type); 186 + if (!fmt) 187 + return NULL; 186 188 } 187 189 188 190 pixmp->width = clamp(pixmp->width, frame_width_min(inst),
+21 -8
drivers/media/platform/qcom/venus/venc.c
··· 192 192 pixmp->height = clamp(pixmp->height, frame_height_min(inst), 193 193 frame_height_max(inst)); 194 194 195 - if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { 196 - pixmp->width = ALIGN(pixmp->width, 128); 197 - pixmp->height = ALIGN(pixmp->height, 32); 198 - } 195 + pixmp->width = ALIGN(pixmp->width, 128); 196 + pixmp->height = ALIGN(pixmp->height, 32); 199 197 200 198 pixmp->width = ALIGN(pixmp->width, 2); 201 199 pixmp->height = ALIGN(pixmp->height, 2); ··· 390 392 struct v4l2_fract *timeperframe = &out->timeperframe; 391 393 u64 us_per_frame, fps; 392 394 393 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 395 + if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 394 396 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 395 397 return -EINVAL; 396 398 ··· 422 424 { 423 425 struct venus_inst *inst = to_inst(file); 424 426 425 - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && 427 + if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && 426 428 a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) 427 429 return -EINVAL; 428 430 ··· 507 509 return 0; 508 510 } 509 511 512 + static int venc_subscribe_event(struct v4l2_fh *fh, 513 + const struct v4l2_event_subscription *sub) 514 + { 515 + switch (sub->type) { 516 + case V4L2_EVENT_EOS: 517 + return v4l2_event_subscribe(fh, sub, 2, NULL); 518 + case V4L2_EVENT_CTRL: 519 + return v4l2_ctrl_subscribe_event(fh, sub); 520 + default: 521 + return -EINVAL; 522 + } 523 + } 524 + 510 525 static const struct v4l2_ioctl_ops venc_ioctl_ops = { 511 526 .vidioc_querycap = venc_querycap, 512 527 .vidioc_enum_fmt_vid_cap = venc_enum_fmt, ··· 545 534 .vidioc_g_parm = venc_g_parm, 546 535 .vidioc_enum_framesizes = venc_enum_framesizes, 547 536 .vidioc_enum_frameintervals = venc_enum_frameintervals, 548 - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 537 + .vidioc_subscribe_event = venc_subscribe_event, 549 538 .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 539 + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, 550 540 }; 551 541 552 542 static int venc_pm_get(struct venus_inst *inst) ··· 698 686 return ret; 699 687 } 700 688 701 - if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC) { 689 + if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_HEVC && 690 + ctr->profile.hevc == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) { 702 691 struct hfi_hdr10_pq_sei hdr10; 703 692 unsigned int c; 704 693
+33 -5
drivers/media/platform/qcom/venus/venc_ctrls.c
··· 8 8 9 9 #include "core.h" 10 10 #include "venc.h" 11 + #include "helpers.h" 11 12 12 13 #define BITRATE_MIN 32000 13 14 #define BITRATE_MAX 160000000 ··· 337 336 * if we disable 8x8 transform for HP. 338 337 */ 339 338 340 - if (ctrl->val == 0) 341 - return -EINVAL; 342 339 343 340 ctr->h264_8x8_transform = ctrl->val; 344 341 break; ··· 347 348 return 0; 348 349 } 349 350 351 + static int venc_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 352 + { 353 + struct venus_inst *inst = ctrl_to_inst(ctrl); 354 + struct hfi_buffer_requirements bufreq; 355 + enum hfi_version ver = inst->core->res->hfi_version; 356 + int ret; 357 + 358 + switch (ctrl->id) { 359 + case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT: 360 + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); 361 + if (!ret) 362 + ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 363 + break; 364 + default: 365 + return -EINVAL; 366 + } 367 + 368 + return 0; 369 + } 370 + 350 371 static const struct v4l2_ctrl_ops venc_ctrl_ops = { 351 372 .s_ctrl = venc_op_s_ctrl, 373 + .g_volatile_ctrl = venc_op_g_volatile_ctrl, 352 374 }; 353 375 354 376 int venc_ctrl_init(struct venus_inst *inst) 355 377 { 356 378 int ret; 379 + struct v4l2_ctrl_hdr10_mastering_display p_hdr10_mastering = { 380 + { 34000, 13250, 7500 }, 381 + { 16000, 34500, 3000 }, 15635, 16450, 10000000, 500, 382 + }; 383 + struct v4l2_ctrl_hdr10_cll_info p_hdr10_cll = { 1000, 400 }; 357 384 358 - ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 58); 385 + ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 59); 359 386 if (ret) 360 387 return ret; 361 388 ··· 460 435 V4L2_CID_MPEG_VIDEO_VP8_PROFILE, 461 436 V4L2_MPEG_VIDEO_VP8_PROFILE_3, 462 437 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0); 438 + 439 + v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 440 + V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 4, 11, 1, 4); 463 441 464 442 v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, 465 443 V4L2_CID_MPEG_VIDEO_BITRATE, BITRATE_MIN, BITRATE_MAX, ··· 607 579 608 580 v4l2_ctrl_new_std_compound(&inst->ctrl_handler, &venc_ctrl_ops, 609 581 V4L2_CID_COLORIMETRY_HDR10_CLL_INFO, 610 - v4l2_ctrl_ptr_create(NULL)); 582 + v4l2_ctrl_ptr_create(&p_hdr10_cll)); 611 583 612 584 v4l2_ctrl_new_std_compound(&inst->ctrl_handler, &venc_ctrl_ops, 613 585 V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY, 614 - v4l2_ctrl_ptr_create(NULL)); 586 + v4l2_ctrl_ptr_create((void *)&p_hdr10_mastering)); 615 587 616 588 v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, 617 589 V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE,
+2 -3
drivers/media/platform/renesas/rcar-vin/rcar-core.c
··· 786 786 return 0; 787 787 788 788 /* 789 - * Don't allow link changes if any entity in the graph is 790 - * streaming, modifying the CHSEL register fields can disrupt 791 - * running streams. 789 + * Don't allow link changes if any stream in the graph is active as 790 + * modifying the CHSEL register fields can disrupt running streams. 792 791 */ 793 792 media_device_for_each_entity(entity, &group->mdev) 794 793 if (media_entity_is_streaming(entity))
+3 -15
drivers/media/platform/renesas/rcar-vin/rcar-dma.c
··· 1244 1244 1245 1245 static int rvin_set_stream(struct rvin_dev *vin, int on) 1246 1246 { 1247 - struct media_pipeline *pipe; 1248 - struct media_device *mdev; 1249 1247 struct v4l2_subdev *sd; 1250 1248 struct media_pad *pad; 1251 1249 int ret; ··· 1263 1265 sd = media_entity_to_v4l2_subdev(pad->entity); 1264 1266 1265 1267 if (!on) { 1266 - media_pipeline_stop(&vin->vdev.entity); 1268 + video_device_pipeline_stop(&vin->vdev); 1267 1269 return v4l2_subdev_call(sd, video, s_stream, 0); 1268 1270 } 1269 1271 ··· 1271 1273 if (ret) 1272 1274 return ret; 1273 1275 1274 - /* 1275 - * The graph lock needs to be taken to protect concurrent 1276 - * starts of multiple VIN instances as they might share 1277 - * a common subdevice down the line and then should use 1278 - * the same pipe. 1279 - */ 1280 - mdev = vin->vdev.entity.graph_obj.mdev; 1281 - mutex_lock(&mdev->graph_mutex); 1282 - pipe = sd->entity.pipe ? sd->entity.pipe : &vin->vdev.pipe; 1283 - ret = __media_pipeline_start(&vin->vdev.entity, pipe); 1284 - mutex_unlock(&mdev->graph_mutex); 1276 + ret = video_device_pipeline_alloc_start(&vin->vdev); 1285 1277 if (ret) 1286 1278 return ret; 1287 1279 ··· 1279 1291 if (ret == -ENOIOCTLCMD) 1280 1292 ret = 0; 1281 1293 if (ret) 1282 - media_pipeline_stop(&vin->vdev.entity); 1294 + video_device_pipeline_stop(&vin->vdev); 1283 1295 1284 1296 return ret; 1285 1297 }
+3 -3
drivers/media/platform/renesas/vsp1/vsp1_video.c
··· 927 927 } 928 928 mutex_unlock(&pipe->lock); 929 929 930 - media_pipeline_stop(&video->video.entity); 930 + video_device_pipeline_stop(&video->video); 931 931 vsp1_video_release_buffers(video); 932 932 vsp1_video_pipeline_put(pipe); 933 933 } ··· 1046 1046 return PTR_ERR(pipe); 1047 1047 } 1048 1048 1049 - ret = __media_pipeline_start(&video->video.entity, &pipe->pipe); 1049 + ret = __video_device_pipeline_start(&video->video, &pipe->pipe); 1050 1050 if (ret < 0) { 1051 1051 mutex_unlock(&mdev->graph_mutex); 1052 1052 goto err_pipe; ··· 1070 1070 return 0; 1071 1071 1072 1072 err_stop: 1073 - media_pipeline_stop(&video->video.entity); 1073 + video_device_pipeline_stop(&video->video); 1074 1074 err_pipe: 1075 1075 vsp1_video_pipeline_put(pipe); 1076 1076 return ret;
+11 -10
drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
··· 913 913 * 914 914 * Call s_stream(false) in the reverse order from 915 915 * rkisp1_pipeline_stream_enable() and disable the DMA engine. 916 - * Should be called before media_pipeline_stop() 916 + * Should be called before video_device_pipeline_stop() 917 917 */ 918 918 static void rkisp1_pipeline_stream_disable(struct rkisp1_capture *cap) 919 919 __must_hold(&cap->rkisp1->stream_lock) ··· 926 926 * If the other capture is streaming, isp and sensor nodes shouldn't 927 927 * be disabled, skip them. 928 928 */ 929 - if (rkisp1->pipe.streaming_count < 2) 929 + if (rkisp1->pipe.start_count < 2) 930 930 v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, false); 931 931 932 932 v4l2_subdev_call(&rkisp1->resizer_devs[cap->id].sd, video, s_stream, ··· 937 937 * rkisp1_pipeline_stream_enable - enable nodes in the pipeline 938 938 * 939 939 * Enable the DMA Engine and call s_stream(true) through the pipeline. 940 - * Should be called after media_pipeline_start() 940 + * Should be called after video_device_pipeline_start() 941 941 */ 942 942 static int rkisp1_pipeline_stream_enable(struct rkisp1_capture *cap) 943 943 __must_hold(&cap->rkisp1->stream_lock) ··· 956 956 * If the other capture is streaming, isp and sensor nodes are already 957 957 * enabled, skip them. 958 958 */ 959 - if (rkisp1->pipe.streaming_count > 1) 959 + if (rkisp1->pipe.start_count > 1) 960 960 return 0; 961 961 962 962 ret = v4l2_subdev_call(&rkisp1->isp.sd, video, s_stream, true); ··· 994 994 995 995 rkisp1_dummy_buf_destroy(cap); 996 996 997 - media_pipeline_stop(&node->vdev.entity); 997 + video_device_pipeline_stop(&node->vdev); 998 998 999 999 mutex_unlock(&cap->rkisp1->stream_lock); 1000 1000 } ··· 1008 1008 1009 1009 mutex_lock(&cap->rkisp1->stream_lock); 1010 1010 1011 - ret = media_pipeline_start(entity, &cap->rkisp1->pipe); 1011 + ret = video_device_pipeline_start(&cap->vnode.vdev, &cap->rkisp1->pipe); 1012 1012 if (ret) { 1013 1013 dev_err(cap->rkisp1->dev, "start pipeline failed %d\n", ret); 1014 1014 goto err_ret_buffers; ··· 1044 1044 err_destroy_dummy: 1045 1045 rkisp1_dummy_buf_destroy(cap); 1046 1046 err_pipeline_stop: 1047 - media_pipeline_stop(entity); 1047 + video_device_pipeline_stop(&cap->vnode.vdev); 1048 1048 err_ret_buffers: 1049 1049 rkisp1_return_all_buffers(cap, VB2_BUF_STATE_QUEUED); 1050 1050 mutex_unlock(&cap->rkisp1->stream_lock); ··· 1273 1273 struct rkisp1_capture *cap = video_get_drvdata(vdev); 1274 1274 const struct rkisp1_capture_fmt_cfg *fmt = 1275 1275 rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat); 1276 - struct v4l2_subdev_format sd_fmt; 1276 + struct v4l2_subdev_format sd_fmt = { 1277 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1278 + .pad = link->source->index, 1279 + }; 1277 1280 int ret; 1278 1281 1279 - sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 1280 - sd_fmt.pad = link->source->index; 1281 1282 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt); 1282 1283 if (ret) 1283 1284 return ret;
+23 -7
drivers/media/platform/rockchip/rkisp1/rkisp1-common.h
··· 378 378 struct v4l2_format vdev_fmt; 379 379 380 380 enum v4l2_quantization quantization; 381 + enum v4l2_ycbcr_encoding ycbcr_encoding; 381 382 enum rkisp1_fmt_raw_pat_type raw_type; 382 383 }; 383 384 ··· 557 556 */ 558 557 const struct rkisp1_mbus_info *rkisp1_mbus_info_get_by_code(u32 mbus_code); 559 558 560 - /* rkisp1_params_configure - configure the params when stream starts. 561 - * This function is called by the isp entity upon stream starts. 562 - * The function applies the initial configuration of the parameters. 559 + /* 560 + * rkisp1_params_pre_configure - Configure the params before stream start 563 561 * 564 - * @params: pointer to rkisp1_params. 562 + * @params: pointer to rkisp1_params 565 563 * @bayer_pat: the bayer pattern on the isp video sink pad 566 564 * @quantization: the quantization configured on the isp's src pad 565 + * @ycbcr_encoding: the ycbcr_encoding configured on the isp's src pad 566 + * 567 + * This function is called by the ISP entity just before the ISP gets started. 568 + * It applies the initial ISP parameters from the first params buffer, but 569 + * skips LSC as it needs to be configured after the ISP is started. 567 570 */ 568 - void rkisp1_params_configure(struct rkisp1_params *params, 569 - enum rkisp1_fmt_raw_pat_type bayer_pat, 570 - enum v4l2_quantization quantization); 571 + void rkisp1_params_pre_configure(struct rkisp1_params *params, 572 + enum rkisp1_fmt_raw_pat_type bayer_pat, 573 + enum v4l2_quantization quantization, 574 + enum v4l2_ycbcr_encoding ycbcr_encoding); 575 + 576 + /* 577 + * rkisp1_params_post_configure - Configure the params after stream start 578 + * 579 + * @params: pointer to rkisp1_params 580 + * 581 + * This function is called by the ISP entity just after the ISP gets started. 582 + * It applies the initial ISP LSC parameters from the first params buffer. 583 + */ 584 + void rkisp1_params_post_configure(struct rkisp1_params *params); 571 585 572 586 /* rkisp1_params_disable - disable all parameters. 573 587 * This function is called by the isp entity upon stream start
+127 -17
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
··· 231 231 struct v4l2_mbus_framefmt *src_frm; 232 232 233 233 src_frm = rkisp1_isp_get_pad_fmt(isp, NULL, 234 - RKISP1_ISP_PAD_SINK_VIDEO, 234 + RKISP1_ISP_PAD_SOURCE_VIDEO, 235 235 V4L2_SUBDEV_FORMAT_ACTIVE); 236 - rkisp1_params_configure(&rkisp1->params, sink_fmt->bayer_pat, 237 - src_frm->quantization); 236 + rkisp1_params_pre_configure(&rkisp1->params, sink_fmt->bayer_pat, 237 + src_frm->quantization, 238 + src_frm->ycbcr_enc); 238 239 } 239 240 240 241 return 0; ··· 341 340 RKISP1_CIF_ISP_CTRL_ISP_ENABLE | 342 341 RKISP1_CIF_ISP_CTRL_ISP_INFORM_ENABLE; 343 342 rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val); 343 + 344 + if (isp->src_fmt->pixel_enc != V4L2_PIXEL_ENC_BAYER) 345 + rkisp1_params_post_configure(&rkisp1->params); 344 346 } 345 347 346 348 /* ---------------------------------------------------------------------------- ··· 435 431 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 436 432 struct v4l2_rect *sink_crop, *src_crop; 437 433 434 + /* Video. */ 438 435 sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 439 436 RKISP1_ISP_PAD_SINK_VIDEO); 440 437 sink_fmt->width = RKISP1_DEFAULT_WIDTH; 441 438 sink_fmt->height = RKISP1_DEFAULT_HEIGHT; 442 439 sink_fmt->field = V4L2_FIELD_NONE; 443 440 sink_fmt->code = RKISP1_DEF_SINK_PAD_FMT; 441 + sink_fmt->colorspace = V4L2_COLORSPACE_RAW; 442 + sink_fmt->xfer_func = V4L2_XFER_FUNC_NONE; 443 + sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; 444 + sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; 444 445 445 446 sink_crop = v4l2_subdev_get_try_crop(sd, sd_state, 446 447 RKISP1_ISP_PAD_SINK_VIDEO); ··· 458 449 RKISP1_ISP_PAD_SOURCE_VIDEO); 459 450 *src_fmt = *sink_fmt; 460 451 src_fmt->code = RKISP1_DEF_SRC_PAD_FMT; 452 + src_fmt->colorspace = V4L2_COLORSPACE_SRGB; 453 + src_fmt->xfer_func = V4L2_XFER_FUNC_SRGB; 454 + src_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; 455 + src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE; 461 456 462 457 src_crop = v4l2_subdev_get_try_crop(sd, sd_state, 463 458 RKISP1_ISP_PAD_SOURCE_VIDEO); 464 459 *src_crop = *sink_crop; 465 460 461 + /* Parameters and statistics. */ 466 462 sink_fmt = v4l2_subdev_get_try_format(sd, sd_state, 467 463 RKISP1_ISP_PAD_SINK_PARAMS); 468 464 src_fmt = v4l2_subdev_get_try_format(sd, sd_state, ··· 486 472 struct v4l2_mbus_framefmt *format, 487 473 unsigned int which) 488 474 { 489 - const struct rkisp1_mbus_info *mbus_info; 475 + const struct rkisp1_mbus_info *sink_info; 476 + const struct rkisp1_mbus_info *src_info; 477 + struct v4l2_mbus_framefmt *sink_fmt; 490 478 struct v4l2_mbus_framefmt *src_fmt; 491 479 const struct v4l2_rect *src_crop; 480 + bool set_csc; 492 481 482 + sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, 483 + RKISP1_ISP_PAD_SINK_VIDEO, which); 493 484 src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, 494 485 RKISP1_ISP_PAD_SOURCE_VIDEO, which); 495 486 src_crop = rkisp1_isp_get_pad_crop(isp, sd_state, 496 487 RKISP1_ISP_PAD_SOURCE_VIDEO, which); 497 488 489 + /* 490 + * Media bus code. The ISP can operate in pass-through mode (Bayer in, 491 + * Bayer out or YUV in, YUV out) or process Bayer data to YUV, but 492 + * can't convert from YUV to Bayer. 493 + */ 494 + sink_info = rkisp1_mbus_info_get_by_code(sink_fmt->code); 495 + 498 496 src_fmt->code = format->code; 499 - mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code); 500 - if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) { 497 + src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); 498 + if (!src_info || !(src_info->direction & RKISP1_ISP_SD_SRC)) { 501 499 src_fmt->code = RKISP1_DEF_SRC_PAD_FMT; 502 - mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code); 500 + src_info = rkisp1_mbus_info_get_by_code(src_fmt->code); 503 501 } 504 - if (which == V4L2_SUBDEV_FORMAT_ACTIVE) 505 - isp->src_fmt = mbus_info; 502 + 503 + if (sink_info->pixel_enc == V4L2_PIXEL_ENC_YUV && 504 + src_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) { 505 + src_fmt->code = sink_fmt->code; 506 + src_info = sink_info; 507 + } 508 + 509 + /* 510 + * The source width and height must be identical to the source crop 511 + * size. 512 + */ 506 513 src_fmt->width = src_crop->width; 507 514 src_fmt->height = src_crop->height; 508 515 509 516 /* 510 - * The CSC API is used to allow userspace to force full 511 - * quantization on YUV formats. 517 + * Copy the color space for the sink pad. When converting from Bayer to 518 + * YUV, default to a limited quantization range. 512 519 */ 513 - if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC && 514 - format->quantization == V4L2_QUANTIZATION_FULL_RANGE && 515 - mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV) 516 - src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; 517 - else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV) 520 + src_fmt->colorspace = sink_fmt->colorspace; 521 + src_fmt->xfer_func = sink_fmt->xfer_func; 522 + src_fmt->ycbcr_enc = sink_fmt->ycbcr_enc; 523 + 524 + if (sink_info->pixel_enc == V4L2_PIXEL_ENC_BAYER && 525 + src_info->pixel_enc == V4L2_PIXEL_ENC_YUV) 518 526 src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE; 519 527 else 520 - src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; 528 + src_fmt->quantization = sink_fmt->quantization; 529 + 530 + /* 531 + * Allow setting the source color space fields when the SET_CSC flag is 532 + * set and the source format is YUV. If the sink format is YUV, don't 533 + * set the color primaries, transfer function or YCbCr encoding as the 534 + * ISP is bypassed in that case and passes YUV data through without 535 + * modifications. 536 + * 537 + * The color primaries and transfer function are configured through the 538 + * cross-talk matrix and tone curve respectively. Settings for those 539 + * hardware blocks are conveyed through the ISP parameters buffer, as 540 + * they need to combine color space information with other image tuning 541 + * characteristics and can't thus be computed by the kernel based on the 542 + * color space. The source pad colorspace and xfer_func fields are thus 543 + * ignored by the driver, but can be set by userspace to propagate 544 + * accurate color space information down the pipeline. 545 + */ 546 + set_csc = format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC; 547 + 548 + if (set_csc && src_info->pixel_enc == V4L2_PIXEL_ENC_YUV) { 549 + if (sink_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) { 550 + if (format->colorspace != V4L2_COLORSPACE_DEFAULT) 551 + src_fmt->colorspace = format->colorspace; 552 + if (format->xfer_func != V4L2_XFER_FUNC_DEFAULT) 553 + src_fmt->xfer_func = format->xfer_func; 554 + if (format->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT) 555 + src_fmt->ycbcr_enc = format->ycbcr_enc; 556 + } 557 + 558 + if (format->quantization != V4L2_QUANTIZATION_DEFAULT) 559 + src_fmt->quantization = format->quantization; 560 + } 521 561 522 562 *format = *src_fmt; 563 + 564 + /* 565 + * Restore the SET_CSC flag if it was set to indicate support for the 566 + * CSC setting API. 567 + */ 568 + if (set_csc) 569 + format->flags |= V4L2_MBUS_FRAMEFMT_SET_CSC; 570 + 571 + /* Store the source format info when setting the active format. */ 572 + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) 573 + isp->src_fmt = src_info; 523 574 } 524 575 525 576 static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp, ··· 652 573 const struct rkisp1_mbus_info *mbus_info; 653 574 struct v4l2_mbus_framefmt *sink_fmt; 654 575 struct v4l2_rect *sink_crop; 576 + bool is_yuv; 655 577 656 578 sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state, 657 579 RKISP1_ISP_PAD_SINK_VIDEO, ··· 672 592 sink_fmt->height = clamp_t(u32, format->height, 673 593 RKISP1_ISP_MIN_HEIGHT, 674 594 RKISP1_ISP_MAX_HEIGHT); 595 + 596 + /* 597 + * Adjust the color space fields. Accept any color primaries and 598 + * transfer function for both YUV and Bayer. For YUV any YCbCr encoding 599 + * and quantization range is also accepted. For Bayer formats, the YCbCr 600 + * encoding isn't applicable, and the quantization range can only be 601 + * full. 602 + */ 603 + is_yuv = mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV; 604 + 605 + sink_fmt->colorspace = format->colorspace ? : 606 + (is_yuv ? V4L2_COLORSPACE_SRGB : 607 + V4L2_COLORSPACE_RAW); 608 + sink_fmt->xfer_func = format->xfer_func ? : 609 + V4L2_MAP_XFER_FUNC_DEFAULT(sink_fmt->colorspace); 610 + if (is_yuv) { 611 + sink_fmt->ycbcr_enc = format->ycbcr_enc ? : 612 + V4L2_MAP_YCBCR_ENC_DEFAULT(sink_fmt->colorspace); 613 + sink_fmt->quantization = format->quantization ? : 614 + V4L2_MAP_QUANTIZATION_DEFAULT(false, sink_fmt->colorspace, 615 + sink_fmt->ycbcr_enc); 616 + } else { 617 + /* 618 + * The YCbCr encoding isn't applicable for non-YUV formats, but 619 + * V4L2 has no "no encoding" value. Hardcode it to Rec. 601, it 620 + * should be ignored by userspace. 621 + */ 622 + sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; 623 + sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; 624 + } 675 625 676 626 *format = *sink_fmt; 677 627
+318 -215
drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
··· 18 18 #define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2 19 19 #define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8 20 20 21 + #define RKISP1_ISP_DPCC_METHODS_SET(n) \ 22 + (RKISP1_CIF_ISP_DPCC_METHODS_SET_1 + 0x4 * (n)) 21 23 #define RKISP1_ISP_DPCC_LINE_THRESH(n) \ 22 24 (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n)) 23 25 #define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \ ··· 58 56 unsigned int i; 59 57 u32 mode; 60 58 61 - /* avoid to override the old enable value */ 59 + /* 60 + * The enable bit is controlled in rkisp1_isp_isr_other_config() and 61 + * must be preserved. The grayscale mode should be configured 62 + * automatically based on the media bus code on the ISP sink pad, so 63 + * only the STAGE1_ENABLE bit can be set by userspace. 64 + */ 62 65 mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE); 63 - mode &= RKISP1_CIF_ISP_DPCC_ENA; 64 - mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA; 66 + mode &= RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE; 67 + mode |= arg->mode & RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE; 65 68 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE, mode); 66 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_OUTPUT_MODE, 67 - arg->output_mode); 68 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_SET_USE, 69 - arg->set_use); 70 69 71 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_METHODS_SET_1, 72 - arg->methods[0].method); 73 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_METHODS_SET_2, 74 - arg->methods[1].method); 75 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_METHODS_SET_3, 76 - arg->methods[2].method); 70 + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_OUTPUT_MODE, 71 + arg->output_mode & RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_MASK); 72 + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_SET_USE, 73 + arg->set_use & RKISP1_CIF_ISP_DPCC_SET_USE_MASK); 74 + 77 75 for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) { 76 + rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_METHODS_SET(i), 77 + arg->methods[i].method & 78 + RKISP1_CIF_ISP_DPCC_METHODS_SET_MASK); 78 79 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_THRESH(i), 79 - arg->methods[i].line_thresh); 80 + arg->methods[i].line_thresh & 81 + RKISP1_CIF_ISP_DPCC_LINE_THRESH_MASK); 80 82 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_LINE_MAD_FAC(i), 81 - arg->methods[i].line_mad_fac); 83 + arg->methods[i].line_mad_fac & 84 + RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_MASK); 82 85 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_PG_FAC(i), 83 - arg->methods[i].pg_fac); 86 + arg->methods[i].pg_fac & 87 + RKISP1_CIF_ISP_DPCC_PG_FAC_MASK); 84 88 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RND_THRESH(i), 85 - arg->methods[i].rnd_thresh); 89 + arg->methods[i].rnd_thresh & 90 + RKISP1_CIF_ISP_DPCC_RND_THRESH_MASK); 86 91 rkisp1_write(params->rkisp1, RKISP1_ISP_DPCC_RG_FAC(i), 87 - arg->methods[i].rg_fac); 92 + arg->methods[i].rg_fac & 93 + RKISP1_CIF_ISP_DPCC_RG_FAC_MASK); 88 94 } 89 95 90 96 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RND_OFFS, 91 - arg->rnd_offs); 97 + arg->rnd_offs & RKISP1_CIF_ISP_DPCC_RND_OFFS_MASK); 92 98 rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_DPCC_RO_LIMITS, 93 - arg->ro_limits); 99 + arg->ro_limits & RKISP1_CIF_ISP_DPCC_RO_LIMIT_MASK); 94 100 } 95 101 96 102 /* ISP black level subtraction interface function */ ··· 198 188 rkisp1_lsc_matrix_config_v10(struct rkisp1_params *params, 199 189 const struct rkisp1_cif_isp_lsc_config *pconfig) 200 190 { 201 - unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data; 191 + struct rkisp1_device *rkisp1 = params->rkisp1; 192 + u32 lsc_status, sram_addr, lsc_table_sel; 193 + unsigned int i, j; 202 194 203 - isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 195 + lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 204 196 205 197 /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ 206 - sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? 198 + sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 207 199 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : 208 200 RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; 209 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 210 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 211 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 212 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 201 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 202 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 203 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 204 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 213 205 214 206 /* program data tables (table size is 9 * 17 = 153) */ 215 207 for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) { 208 + const __u16 *r_tbl = pconfig->r_data_tbl[i]; 209 + const __u16 *gr_tbl = pconfig->gr_data_tbl[i]; 210 + const __u16 *gb_tbl = pconfig->gb_data_tbl[i]; 211 + const __u16 *b_tbl = pconfig->b_data_tbl[i]; 212 + 216 213 /* 217 214 * 17 sectors with 2 values in one DWORD = 9 218 215 * DWORDs (2nd value of last DWORD unused) 219 216 */ 220 217 for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) { 221 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->r_data_tbl[i][j], 222 - pconfig->r_data_tbl[i][j + 1]); 223 - rkisp1_write(params->rkisp1, 224 - RKISP1_CIF_ISP_LSC_R_TABLE_DATA, data); 225 - 226 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gr_data_tbl[i][j], 227 - pconfig->gr_data_tbl[i][j + 1]); 228 - rkisp1_write(params->rkisp1, 229 - RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, data); 230 - 231 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gb_data_tbl[i][j], 232 - pconfig->gb_data_tbl[i][j + 1]); 233 - rkisp1_write(params->rkisp1, 234 - RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, data); 235 - 236 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->b_data_tbl[i][j], 237 - pconfig->b_data_tbl[i][j + 1]); 238 - rkisp1_write(params->rkisp1, 239 - RKISP1_CIF_ISP_LSC_B_TABLE_DATA, data); 218 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 219 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 220 + r_tbl[j], r_tbl[j + 1])); 221 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 222 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 223 + gr_tbl[j], gr_tbl[j + 1])); 224 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 225 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 226 + gb_tbl[j], gb_tbl[j + 1])); 227 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 228 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10( 229 + b_tbl[j], b_tbl[j + 1])); 240 230 } 241 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->r_data_tbl[i][j], 0); 242 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 243 - data); 244 231 245 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gr_data_tbl[i][j], 0); 246 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 247 - data); 248 - 249 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->gb_data_tbl[i][j], 0); 250 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 251 - data); 252 - 253 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(pconfig->b_data_tbl[i][j], 0); 254 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 255 - data); 232 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 233 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(r_tbl[j], 0)); 234 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 235 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gr_tbl[j], 0)); 236 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 237 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(gb_tbl[j], 0)); 238 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 239 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V10(b_tbl[j], 0)); 256 240 } 257 - isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? 258 - RKISP1_CIF_ISP_LSC_TABLE_0 : 259 - RKISP1_CIF_ISP_LSC_TABLE_1; 260 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, 261 - isp_lsc_table_sel); 241 + 242 + lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 243 + RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1; 244 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel); 262 245 } 263 246 264 247 static void 265 248 rkisp1_lsc_matrix_config_v12(struct rkisp1_params *params, 266 249 const struct rkisp1_cif_isp_lsc_config *pconfig) 267 250 { 268 - unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data; 251 + struct rkisp1_device *rkisp1 = params->rkisp1; 252 + u32 lsc_status, sram_addr, lsc_table_sel; 253 + unsigned int i, j; 269 254 270 - isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 255 + lsc_status = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_STATUS); 271 256 272 257 /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ 273 - sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? 274 - RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : 275 - RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; 276 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 277 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 278 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 279 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 258 + sram_addr = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 259 + RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : 260 + RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; 261 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_ADDR, sram_addr); 262 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR, sram_addr); 263 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR, sram_addr); 264 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_ADDR, sram_addr); 280 265 281 266 /* program data tables (table size is 9 * 17 = 153) */ 282 267 for (i = 0; i < RKISP1_CIF_ISP_LSC_SAMPLES_MAX; i++) { 268 + const __u16 *r_tbl = pconfig->r_data_tbl[i]; 269 + const __u16 *gr_tbl = pconfig->gr_data_tbl[i]; 270 + const __u16 *gb_tbl = pconfig->gb_data_tbl[i]; 271 + const __u16 *b_tbl = pconfig->b_data_tbl[i]; 272 + 283 273 /* 284 274 * 17 sectors with 2 values in one DWORD = 9 285 275 * DWORDs (2nd value of last DWORD unused) 286 276 */ 287 277 for (j = 0; j < RKISP1_CIF_ISP_LSC_SAMPLES_MAX - 1; j += 2) { 288 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 289 - pconfig->r_data_tbl[i][j], 290 - pconfig->r_data_tbl[i][j + 1]); 291 - rkisp1_write(params->rkisp1, 292 - RKISP1_CIF_ISP_LSC_R_TABLE_DATA, data); 293 - 294 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 295 - pconfig->gr_data_tbl[i][j], 296 - pconfig->gr_data_tbl[i][j + 1]); 297 - rkisp1_write(params->rkisp1, 298 - RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, data); 299 - 300 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 301 - pconfig->gb_data_tbl[i][j], 302 - pconfig->gb_data_tbl[i][j + 1]); 303 - rkisp1_write(params->rkisp1, 304 - RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, data); 305 - 306 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 307 - pconfig->b_data_tbl[i][j], 308 - pconfig->b_data_tbl[i][j + 1]); 309 - rkisp1_write(params->rkisp1, 310 - RKISP1_CIF_ISP_LSC_B_TABLE_DATA, data); 278 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 279 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 280 + r_tbl[j], r_tbl[j + 1])); 281 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 282 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 283 + gr_tbl[j], gr_tbl[j + 1])); 284 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 285 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 286 + gb_tbl[j], gb_tbl[j + 1])); 287 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 288 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12( 289 + b_tbl[j], b_tbl[j + 1])); 311 290 } 312 291 313 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->r_data_tbl[i][j], 0); 314 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 315 - data); 316 - 317 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gr_data_tbl[i][j], 0); 318 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 319 - data); 320 - 321 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->gb_data_tbl[i][j], 0); 322 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 323 - data); 324 - 325 - data = RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(pconfig->b_data_tbl[i][j], 0); 326 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 327 - data); 292 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_R_TABLE_DATA, 293 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(r_tbl[j], 0)); 294 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GR_TABLE_DATA, 295 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gr_tbl[j], 0)); 296 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_GB_TABLE_DATA, 297 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(gb_tbl[j], 0)); 298 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_B_TABLE_DATA, 299 + RKISP1_CIF_ISP_LSC_TABLE_DATA_V12(b_tbl[j], 0)); 328 300 } 329 - isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? 330 - RKISP1_CIF_ISP_LSC_TABLE_0 : 331 - RKISP1_CIF_ISP_LSC_TABLE_1; 332 - rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, 333 - isp_lsc_table_sel); 301 + 302 + lsc_table_sel = lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE ? 303 + RKISP1_CIF_ISP_LSC_TABLE_0 : RKISP1_CIF_ISP_LSC_TABLE_1; 304 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_TABLE_SEL, lsc_table_sel); 334 305 } 335 306 336 307 static void rkisp1_lsc_config(struct rkisp1_params *params, 337 308 const struct rkisp1_cif_isp_lsc_config *arg) 338 309 { 339 - unsigned int i, data; 340 - u32 lsc_ctrl; 310 + struct rkisp1_device *rkisp1 = params->rkisp1; 311 + u32 lsc_ctrl, data; 312 + unsigned int i; 341 313 342 314 /* To config must be off , store the current status firstly */ 343 - lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL); 315 + lsc_ctrl = rkisp1_read(rkisp1, RKISP1_CIF_ISP_LSC_CTRL); 344 316 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 345 317 RKISP1_CIF_ISP_LSC_CTRL_ENA); 346 318 params->ops->lsc_matrix_config(params, arg); ··· 331 339 /* program x size tables */ 332 340 data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2], 333 341 arg->x_size_tbl[i * 2 + 1]); 334 - rkisp1_write(params->rkisp1, 335 - RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4, data); 342 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XSIZE(i), data); 336 343 337 344 /* program x grad tables */ 338 - data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2], 345 + data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2], 339 346 arg->x_grad_tbl[i * 2 + 1]); 340 - rkisp1_write(params->rkisp1, 341 - RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4, data); 347 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_XGRAD(i), data); 342 348 343 349 /* program y size tables */ 344 350 data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2], 345 351 arg->y_size_tbl[i * 2 + 1]); 346 - rkisp1_write(params->rkisp1, 347 - RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4, data); 352 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YSIZE(i), data); 348 353 349 354 /* program y grad tables */ 350 - data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2], 355 + data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2], 351 356 arg->y_grad_tbl[i * 2 + 1]); 352 - rkisp1_write(params->rkisp1, 353 - RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4, data); 357 + rkisp1_write(rkisp1, RKISP1_CIF_ISP_LSC_YGRAD(i), data); 354 358 } 355 359 356 360 /* restore the lsc ctrl status */ 357 - if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) { 358 - rkisp1_param_set_bits(params, 359 - RKISP1_CIF_ISP_LSC_CTRL, 361 + if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) 362 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 360 363 RKISP1_CIF_ISP_LSC_CTRL_ENA); 361 - } else { 362 - rkisp1_param_clear_bits(params, 363 - RKISP1_CIF_ISP_LSC_CTRL, 364 + else 365 + rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 364 366 RKISP1_CIF_ISP_LSC_CTRL_ENA); 365 - } 366 367 } 367 368 368 369 /* ISP Filtering function */ ··· 1051 1066 } 1052 1067 } 1053 1068 1054 - static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range) 1069 + static void rkisp1_csm_config(struct rkisp1_params *params) 1055 1070 { 1056 - static const u16 full_range_coeff[] = { 1057 - 0x0026, 0x004b, 0x000f, 1058 - 0x01ea, 0x01d6, 0x0040, 1059 - 0x0040, 0x01ca, 0x01f6 1071 + struct csm_coeffs { 1072 + u16 limited[9]; 1073 + u16 full[9]; 1060 1074 }; 1061 - static const u16 limited_range_coeff[] = { 1062 - 0x0021, 0x0040, 0x000d, 1063 - 0x01ed, 0x01db, 0x0038, 1064 - 0x0038, 0x01d1, 0x01f7, 1075 + static const struct csm_coeffs rec601_coeffs = { 1076 + .limited = { 1077 + 0x0021, 0x0042, 0x000d, 1078 + 0x01ed, 0x01db, 0x0038, 1079 + 0x0038, 0x01d1, 0x01f7, 1080 + }, 1081 + .full = { 1082 + 0x0026, 0x004b, 0x000f, 1083 + 0x01ea, 0x01d6, 0x0040, 1084 + 0x0040, 0x01ca, 0x01f6, 1085 + }, 1065 1086 }; 1087 + static const struct csm_coeffs rec709_coeffs = { 1088 + .limited = { 1089 + 0x0018, 0x0050, 0x0008, 1090 + 0x01f3, 0x01d5, 0x0038, 1091 + 0x0038, 0x01cd, 0x01fb, 1092 + }, 1093 + .full = { 1094 + 0x001b, 0x005c, 0x0009, 1095 + 0x01f1, 0x01cf, 0x0040, 1096 + 0x0040, 0x01c6, 0x01fa, 1097 + }, 1098 + }; 1099 + static const struct csm_coeffs rec2020_coeffs = { 1100 + .limited = { 1101 + 0x001d, 0x004c, 0x0007, 1102 + 0x01f0, 0x01d8, 0x0038, 1103 + 0x0038, 0x01cd, 0x01fb, 1104 + }, 1105 + .full = { 1106 + 0x0022, 0x0057, 0x0008, 1107 + 0x01ee, 0x01d2, 0x0040, 1108 + 0x0040, 0x01c5, 0x01fb, 1109 + }, 1110 + }; 1111 + static const struct csm_coeffs smpte240m_coeffs = { 1112 + .limited = { 1113 + 0x0018, 0x004f, 0x000a, 1114 + 0x01f3, 0x01d5, 0x0038, 1115 + 0x0038, 0x01ce, 0x01fa, 1116 + }, 1117 + .full = { 1118 + 0x001b, 0x005a, 0x000b, 1119 + 0x01f1, 0x01cf, 0x0040, 1120 + 0x0040, 0x01c7, 0x01f9, 1121 + }, 1122 + }; 1123 + 1124 + const struct csm_coeffs *coeffs; 1125 + const u16 *csm; 1066 1126 unsigned int i; 1067 1127 1068 - if (full_range) { 1069 - for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++) 1070 - rkisp1_write(params->rkisp1, 1071 - RKISP1_CIF_ISP_CC_COEFF_0 + i * 4, 1072 - full_range_coeff[i]); 1128 + switch (params->ycbcr_encoding) { 1129 + case V4L2_YCBCR_ENC_601: 1130 + default: 1131 + coeffs = &rec601_coeffs; 1132 + break; 1133 + case V4L2_YCBCR_ENC_709: 1134 + coeffs = &rec709_coeffs; 1135 + break; 1136 + case V4L2_YCBCR_ENC_BT2020: 1137 + coeffs = &rec2020_coeffs; 1138 + break; 1139 + case V4L2_YCBCR_ENC_SMPTE240M: 1140 + coeffs = &smpte240m_coeffs; 1141 + break; 1142 + } 1073 1143 1144 + if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) { 1145 + csm = coeffs->full; 1074 1146 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1075 1147 RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | 1076 1148 RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); 1077 1149 } else { 1078 - for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++) 1079 - rkisp1_write(params->rkisp1, 1080 - RKISP1_CIF_ISP_CC_COEFF_0 + i * 4, 1081 - limited_range_coeff[i]); 1082 - 1150 + csm = coeffs->limited; 1083 1151 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, 1084 1152 RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | 1085 1153 RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); 1086 1154 } 1155 + 1156 + for (i = 0; i < 9; i++) 1157 + rkisp1_write(params->rkisp1, RKISP1_CIF_ISP_CC_COEFF_0 + i * 4, 1158 + csm[i]); 1087 1159 } 1088 1160 1089 1161 /* ISP De-noise Pre-Filter(DPF) function */ ··· 1258 1216 if (module_ens & RKISP1_CIF_ISP_MODULE_DPCC) 1259 1217 rkisp1_param_set_bits(params, 1260 1218 RKISP1_CIF_ISP_DPCC_MODE, 1261 - RKISP1_CIF_ISP_DPCC_ENA); 1219 + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1262 1220 else 1263 1221 rkisp1_param_clear_bits(params, 1264 1222 RKISP1_CIF_ISP_DPCC_MODE, 1265 - RKISP1_CIF_ISP_DPCC_ENA); 1223 + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1266 1224 } 1267 1225 1268 1226 /* update bls config */ ··· 1295 1253 rkisp1_param_clear_bits(params, 1296 1254 RKISP1_CIF_ISP_CTRL, 1297 1255 RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); 1298 - } 1299 - 1300 - /* update lsc config */ 1301 - if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC) 1302 - rkisp1_lsc_config(params, 1303 - &new_params->others.lsc_config); 1304 - 1305 - if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) { 1306 - if (module_ens & RKISP1_CIF_ISP_MODULE_LSC) 1307 - rkisp1_param_set_bits(params, 1308 - RKISP1_CIF_ISP_LSC_CTRL, 1309 - RKISP1_CIF_ISP_LSC_CTRL_ENA); 1310 - else 1311 - rkisp1_param_clear_bits(params, 1312 - RKISP1_CIF_ISP_LSC_CTRL, 1313 - RKISP1_CIF_ISP_LSC_CTRL_ENA); 1314 1256 } 1315 1257 1316 1258 /* update awb gains */ ··· 1413 1387 } 1414 1388 } 1415 1389 1390 + static void 1391 + rkisp1_isp_isr_lsc_config(struct rkisp1_params *params, 1392 + const struct rkisp1_params_cfg *new_params) 1393 + { 1394 + unsigned int module_en_update, module_cfg_update, module_ens; 1395 + 1396 + module_en_update = new_params->module_en_update; 1397 + module_cfg_update = new_params->module_cfg_update; 1398 + module_ens = new_params->module_ens; 1399 + 1400 + /* update lsc config */ 1401 + if (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC) 1402 + rkisp1_lsc_config(params, 1403 + &new_params->others.lsc_config); 1404 + 1405 + if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) { 1406 + if (module_ens & RKISP1_CIF_ISP_MODULE_LSC) 1407 + rkisp1_param_set_bits(params, 1408 + RKISP1_CIF_ISP_LSC_CTRL, 1409 + RKISP1_CIF_ISP_LSC_CTRL_ENA); 1410 + else 1411 + rkisp1_param_clear_bits(params, 1412 + RKISP1_CIF_ISP_LSC_CTRL, 1413 + RKISP1_CIF_ISP_LSC_CTRL_ENA); 1414 + } 1415 + } 1416 + 1416 1417 static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params, 1417 1418 struct rkisp1_params_cfg *new_params) 1418 1419 { ··· 1501 1448 } 1502 1449 } 1503 1450 1504 - static void rkisp1_params_apply_params_cfg(struct rkisp1_params *params, 1505 - unsigned int frame_sequence) 1451 + static bool rkisp1_params_get_buffer(struct rkisp1_params *params, 1452 + struct rkisp1_buffer **buf, 1453 + struct rkisp1_params_cfg **cfg) 1506 1454 { 1507 - struct rkisp1_params_cfg *new_params; 1508 - struct rkisp1_buffer *cur_buf = NULL; 1509 - 1510 1455 if (list_empty(&params->params)) 1511 - return; 1456 + return false; 1512 1457 1513 - cur_buf = list_first_entry(&params->params, 1514 - struct rkisp1_buffer, queue); 1458 + *buf = list_first_entry(&params->params, struct rkisp1_buffer, queue); 1459 + *cfg = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0); 1515 1460 1516 - new_params = (struct rkisp1_params_cfg *)vb2_plane_vaddr(&cur_buf->vb.vb2_buf, 0); 1461 + return true; 1462 + } 1517 1463 1518 - rkisp1_isp_isr_other_config(params, new_params); 1519 - rkisp1_isp_isr_meas_config(params, new_params); 1464 + static void rkisp1_params_complete_buffer(struct rkisp1_params *params, 1465 + struct rkisp1_buffer *buf, 1466 + unsigned int frame_sequence) 1467 + { 1468 + list_del(&buf->queue); 1520 1469 1521 - /* update shadow register immediately */ 1522 - rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 1523 - 1524 - list_del(&cur_buf->queue); 1525 - 1526 - cur_buf->vb.sequence = frame_sequence; 1527 - vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); 1470 + buf->vb.sequence = frame_sequence; 1471 + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); 1528 1472 } 1529 1473 1530 1474 void rkisp1_params_isr(struct rkisp1_device *rkisp1) 1531 1475 { 1532 - /* 1533 - * This isr is called when the ISR finishes processing a frame (RKISP1_CIF_ISP_FRAME). 1534 - * Configurations performed here will be applied on the next frame. 1535 - * Since frame_sequence is updated on the vertical sync signal, we should use 1536 - * frame_sequence + 1 here to indicate to userspace on which frame these parameters 1537 - * are being applied. 1538 - */ 1539 - unsigned int frame_sequence = rkisp1->isp.frame_sequence + 1; 1540 1476 struct rkisp1_params *params = &rkisp1->params; 1477 + struct rkisp1_params_cfg *new_params; 1478 + struct rkisp1_buffer *cur_buf; 1541 1479 1542 1480 spin_lock(&params->config_lock); 1543 - rkisp1_params_apply_params_cfg(params, frame_sequence); 1544 1481 1482 + if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1483 + goto unlock; 1484 + 1485 + rkisp1_isp_isr_other_config(params, new_params); 1486 + rkisp1_isp_isr_lsc_config(params, new_params); 1487 + rkisp1_isp_isr_meas_config(params, new_params); 1488 + 1489 + /* update shadow register immediately */ 1490 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1491 + RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 1492 + 1493 + /* 1494 + * This isr is called when the ISR finishes processing a frame 1495 + * (RKISP1_CIF_ISP_FRAME). Configurations performed here will be 1496 + * applied on the next frame. Since frame_sequence is updated on the 1497 + * vertical sync signal, we should use frame_sequence + 1 here to 1498 + * indicate to userspace on which frame these parameters are being 1499 + * applied. 1500 + */ 1501 + rkisp1_params_complete_buffer(params, cur_buf, 1502 + rkisp1->isp.frame_sequence + 1); 1503 + 1504 + unlock: 1545 1505 spin_unlock(&params->config_lock); 1546 1506 } 1547 1507 ··· 1597 1531 14 1598 1532 }; 1599 1533 1600 - static void rkisp1_params_config_parameter(struct rkisp1_params *params) 1534 + void rkisp1_params_pre_configure(struct rkisp1_params *params, 1535 + enum rkisp1_fmt_raw_pat_type bayer_pat, 1536 + enum v4l2_quantization quantization, 1537 + enum v4l2_ycbcr_encoding ycbcr_encoding) 1601 1538 { 1602 1539 struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; 1540 + struct rkisp1_params_cfg *new_params; 1541 + struct rkisp1_buffer *cur_buf; 1542 + 1543 + params->quantization = quantization; 1544 + params->ycbcr_encoding = ycbcr_encoding; 1545 + params->raw_type = bayer_pat; 1603 1546 1604 1547 params->ops->awb_meas_config(params, &rkisp1_awb_params_default_config); 1605 1548 params->ops->awb_meas_enable(params, &rkisp1_awb_params_default_config, ··· 1627 1552 rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10, 1628 1553 rkisp1_hst_params_default_config.mode); 1629 1554 1630 - /* set the range */ 1631 - if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) 1632 - rkisp1_csm_config(params, true); 1633 - else 1634 - rkisp1_csm_config(params, false); 1555 + rkisp1_csm_config(params); 1635 1556 1636 1557 spin_lock_irq(&params->config_lock); 1637 1558 1638 1559 /* apply the first buffer if there is one already */ 1639 - rkisp1_params_apply_params_cfg(params, 0); 1640 1560 1561 + if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1562 + goto unlock; 1563 + 1564 + rkisp1_isp_isr_other_config(params, new_params); 1565 + rkisp1_isp_isr_meas_config(params, new_params); 1566 + 1567 + /* update shadow register immediately */ 1568 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1569 + RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 1570 + 1571 + unlock: 1641 1572 spin_unlock_irq(&params->config_lock); 1642 1573 } 1643 1574 1644 - void rkisp1_params_configure(struct rkisp1_params *params, 1645 - enum rkisp1_fmt_raw_pat_type bayer_pat, 1646 - enum v4l2_quantization quantization) 1575 + void rkisp1_params_post_configure(struct rkisp1_params *params) 1647 1576 { 1648 - params->quantization = quantization; 1649 - params->raw_type = bayer_pat; 1650 - rkisp1_params_config_parameter(params); 1577 + struct rkisp1_params_cfg *new_params; 1578 + struct rkisp1_buffer *cur_buf; 1579 + 1580 + spin_lock_irq(&params->config_lock); 1581 + 1582 + /* 1583 + * Apply LSC parameters from the first buffer (if any is already 1584 + * available. This must be done after the ISP gets started in the 1585 + * ISP8000Nano v18.02 (found in the i.MX8MP) as access to the LSC RAM 1586 + * is gated by the ISP_CTRL.ISP_ENABLE bit. As this initialization 1587 + * ordering doesn't affect other ISP versions negatively, do so 1588 + * unconditionally. 1589 + */ 1590 + 1591 + if (!rkisp1_params_get_buffer(params, &cur_buf, &new_params)) 1592 + goto unlock; 1593 + 1594 + rkisp1_isp_isr_lsc_config(params, new_params); 1595 + 1596 + /* update shadow register immediately */ 1597 + rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, 1598 + RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD); 1599 + 1600 + rkisp1_params_complete_buffer(params, cur_buf, 0); 1601 + 1602 + unlock: 1603 + spin_unlock_irq(&params->config_lock); 1651 1604 } 1652 1605 1653 1606 /* ··· 1685 1582 void rkisp1_params_disable(struct rkisp1_params *params) 1686 1583 { 1687 1584 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, 1688 - RKISP1_CIF_ISP_DPCC_ENA); 1585 + RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE); 1689 1586 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, 1690 1587 RKISP1_CIF_ISP_LSC_CTRL_ENA); 1691 1588 rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL,
+17 -30
drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
··· 576 576 (((v0) & 0x1FFF) | (((v1) & 0x1FFF) << 13)) 577 577 #define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1) \ 578 578 (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16)) 579 - #define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1) \ 579 + #define RKISP1_CIF_ISP_LSC_SECT_GRAD(v0, v1) \ 580 580 (((v0) & 0xFFF) | (((v1) & 0xFFF) << 16)) 581 581 582 582 /* LSC: ISP_LSC_TABLE_SEL */ ··· 618 618 #define RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA_READ(x) (((x) >> 11) & 1) 619 619 620 620 /* DPCC */ 621 - /* ISP_DPCC_MODE */ 622 - #define RKISP1_CIF_ISP_DPCC_ENA BIT(0) 623 - #define RKISP1_CIF_ISP_DPCC_MODE_MAX 0x07 624 - #define RKISP1_CIF_ISP_DPCC_OUTPUTMODE_MAX 0x0F 625 - #define RKISP1_CIF_ISP_DPCC_SETUSE_MAX 0x0F 626 - #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RESERVED 0xFFFFE000 627 - #define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RESERVED 0xFFFF0000 628 - #define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RESERVED 0xFFFFC0C0 629 - #define RKISP1_CIF_ISP_DPCC_PG_FAC_RESERVED 0xFFFFC0C0 630 - #define RKISP1_CIF_ISP_DPCC_RND_THRESH_RESERVED 0xFFFF0000 631 - #define RKISP1_CIF_ISP_DPCC_RG_FAC_RESERVED 0xFFFFC0C0 632 - #define RKISP1_CIF_ISP_DPCC_RO_LIMIT_RESERVED 0xFFFFF000 633 - #define RKISP1_CIF_ISP_DPCC_RND_OFFS_RESERVED 0xFFFFF000 621 + #define RKISP1_CIF_ISP_DPCC_MODE_DPCC_ENABLE BIT(0) 622 + #define RKISP1_CIF_ISP_DPCC_MODE_GRAYSCALE_MODE BIT(1) 623 + #define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_MASK GENMASK(3, 0) 624 + #define RKISP1_CIF_ISP_DPCC_SET_USE_MASK GENMASK(3, 0) 625 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_MASK 0x00001f1f 626 + #define RKISP1_CIF_ISP_DPCC_LINE_THRESH_MASK 0x0000ffff 627 + #define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_MASK 0x00003f3f 628 + #define RKISP1_CIF_ISP_DPCC_PG_FAC_MASK 0x00003f3f 629 + #define RKISP1_CIF_ISP_DPCC_RND_THRESH_MASK 0x0000ffff 630 + #define RKISP1_CIF_ISP_DPCC_RG_FAC_MASK 0x00003f3f 631 + #define RKISP1_CIF_ISP_DPCC_RO_LIMIT_MASK 0x00000fff 632 + #define RKISP1_CIF_ISP_DPCC_RND_OFFS_MASK 0x00000fff 634 633 635 634 /* BLS */ 636 635 /* ISP_BLS_CTRL */ ··· 1072 1073 #define RKISP1_CIF_ISP_LSC_GR_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000018) 1073 1074 #define RKISP1_CIF_ISP_LSC_B_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x0000001C) 1074 1075 #define RKISP1_CIF_ISP_LSC_GB_TABLE_DATA (RKISP1_CIF_ISP_LSC_BASE + 0x00000020) 1075 - #define RKISP1_CIF_ISP_LSC_XGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000024) 1076 - #define RKISP1_CIF_ISP_LSC_XGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000028) 1077 - #define RKISP1_CIF_ISP_LSC_XGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000002C) 1078 - #define RKISP1_CIF_ISP_LSC_XGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000030) 1079 - #define RKISP1_CIF_ISP_LSC_YGRAD_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000034) 1080 - #define RKISP1_CIF_ISP_LSC_YGRAD_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000038) 1081 - #define RKISP1_CIF_ISP_LSC_YGRAD_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000003C) 1082 - #define RKISP1_CIF_ISP_LSC_YGRAD_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000040) 1083 - #define RKISP1_CIF_ISP_LSC_XSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000044) 1084 - #define RKISP1_CIF_ISP_LSC_XSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000048) 1085 - #define RKISP1_CIF_ISP_LSC_XSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000004C) 1086 - #define RKISP1_CIF_ISP_LSC_XSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000050) 1087 - #define RKISP1_CIF_ISP_LSC_YSIZE_01 (RKISP1_CIF_ISP_LSC_BASE + 0x00000054) 1088 - #define RKISP1_CIF_ISP_LSC_YSIZE_23 (RKISP1_CIF_ISP_LSC_BASE + 0x00000058) 1089 - #define RKISP1_CIF_ISP_LSC_YSIZE_45 (RKISP1_CIF_ISP_LSC_BASE + 0x0000005C) 1090 - #define RKISP1_CIF_ISP_LSC_YSIZE_67 (RKISP1_CIF_ISP_LSC_BASE + 0x00000060) 1076 + #define RKISP1_CIF_ISP_LSC_XGRAD(n) (RKISP1_CIF_ISP_LSC_BASE + 0x00000024 + (n) * 4) 1077 + #define RKISP1_CIF_ISP_LSC_YGRAD(n) (RKISP1_CIF_ISP_LSC_BASE + 0x00000034 + (n) * 4) 1078 + #define RKISP1_CIF_ISP_LSC_XSIZE(n) (RKISP1_CIF_ISP_LSC_BASE + 0x00000044 + (n) * 4) 1079 + #define RKISP1_CIF_ISP_LSC_YSIZE(n) (RKISP1_CIF_ISP_LSC_BASE + 0x00000054 + (n) * 4) 1091 1080 #define RKISP1_CIF_ISP_LSC_TABLE_SEL (RKISP1_CIF_ISP_LSC_BASE + 0x00000064) 1092 1081 #define RKISP1_CIF_ISP_LSC_STATUS (RKISP1_CIF_ISP_LSC_BASE + 0x00000068) 1093 1082
+42 -3
drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
··· 411 411 sink_fmt->height = RKISP1_DEFAULT_HEIGHT; 412 412 sink_fmt->field = V4L2_FIELD_NONE; 413 413 sink_fmt->code = RKISP1_DEF_FMT; 414 + sink_fmt->colorspace = V4L2_COLORSPACE_SRGB; 415 + sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB; 416 + sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; 417 + sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE; 414 418 415 419 sink_crop = v4l2_subdev_get_try_crop(sd, sd_state, 416 420 RKISP1_RSZ_PAD_SINK); ··· 507 503 const struct rkisp1_mbus_info *mbus_info; 508 504 struct v4l2_mbus_framefmt *sink_fmt, *src_fmt; 509 505 struct v4l2_rect *sink_crop; 506 + bool is_yuv; 510 507 511 508 sink_fmt = rkisp1_rsz_get_pad_fmt(rsz, sd_state, RKISP1_RSZ_PAD_SINK, 512 509 which); ··· 529 524 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) 530 525 rsz->pixel_enc = mbus_info->pixel_enc; 531 526 532 - /* Propagete to source pad */ 533 - src_fmt->code = sink_fmt->code; 534 - 535 527 sink_fmt->width = clamp_t(u32, format->width, 536 528 RKISP1_ISP_MIN_WIDTH, 537 529 RKISP1_ISP_MAX_WIDTH); ··· 536 534 RKISP1_ISP_MIN_HEIGHT, 537 535 RKISP1_ISP_MAX_HEIGHT); 538 536 537 + /* 538 + * Adjust the color space fields. Accept any color primaries and 539 + * transfer function for both YUV and Bayer. For YUV any YCbCr encoding 540 + * and quantization range is also accepted. For Bayer formats, the YCbCr 541 + * encoding isn't applicable, and the quantization range can only be 542 + * full. 543 + */ 544 + is_yuv = mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV; 545 + 546 + sink_fmt->colorspace = format->colorspace ? : 547 + (is_yuv ? V4L2_COLORSPACE_SRGB : 548 + V4L2_COLORSPACE_RAW); 549 + sink_fmt->xfer_func = format->xfer_func ? : 550 + V4L2_MAP_XFER_FUNC_DEFAULT(sink_fmt->colorspace); 551 + if (is_yuv) { 552 + sink_fmt->ycbcr_enc = format->ycbcr_enc ? : 553 + V4L2_MAP_YCBCR_ENC_DEFAULT(sink_fmt->colorspace); 554 + sink_fmt->quantization = format->quantization ? : 555 + V4L2_MAP_QUANTIZATION_DEFAULT(false, sink_fmt->colorspace, 556 + sink_fmt->ycbcr_enc); 557 + } else { 558 + /* 559 + * The YCbCr encoding isn't applicable for non-YUV formats, but 560 + * V4L2 has no "no encoding" value. Hardcode it to Rec. 601, it 561 + * should be ignored by userspace. 562 + */ 563 + sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; 564 + sink_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; 565 + } 566 + 539 567 *format = *sink_fmt; 568 + 569 + /* Propagate the media bus code and color space to the source pad. */ 570 + src_fmt->code = sink_fmt->code; 571 + src_fmt->colorspace = sink_fmt->colorspace; 572 + src_fmt->xfer_func = sink_fmt->xfer_func; 573 + src_fmt->ycbcr_enc = sink_fmt->ycbcr_enc; 574 + src_fmt->quantization = sink_fmt->quantization; 540 575 541 576 /* Update sink crop */ 542 577 rkisp1_rsz_set_sink_crop(rsz, sd_state, sink_crop, which);
+4 -5
drivers/media/platform/samsung/exynos4-is/fimc-capture.c
··· 524 524 mutex_lock(&fimc->lock); 525 525 526 526 if (close && vc->streaming) { 527 - media_pipeline_stop(&vc->ve.vdev.entity); 527 + video_device_pipeline_stop(&vc->ve.vdev); 528 528 vc->streaming = false; 529 529 } 530 530 ··· 1176 1176 { 1177 1177 struct fimc_dev *fimc = video_drvdata(file); 1178 1178 struct fimc_vid_cap *vc = &fimc->vid_cap; 1179 - struct media_entity *entity = &vc->ve.vdev.entity; 1180 1179 struct fimc_source_info *si = NULL; 1181 1180 struct v4l2_subdev *sd; 1182 1181 int ret; ··· 1183 1184 if (fimc_capture_active(fimc)) 1184 1185 return -EBUSY; 1185 1186 1186 - ret = media_pipeline_start(entity, &vc->ve.pipe->mp); 1187 + ret = video_device_pipeline_start(&vc->ve.vdev, &vc->ve.pipe->mp); 1187 1188 if (ret < 0) 1188 1189 return ret; 1189 1190 ··· 1217 1218 } 1218 1219 1219 1220 err_p_stop: 1220 - media_pipeline_stop(entity); 1221 + video_device_pipeline_stop(&vc->ve.vdev); 1221 1222 return ret; 1222 1223 } 1223 1224 ··· 1233 1234 return ret; 1234 1235 1235 1236 if (vc->streaming) { 1236 - media_pipeline_stop(&vc->ve.vdev.entity); 1237 + video_device_pipeline_stop(&vc->ve.vdev); 1237 1238 vc->streaming = false; 1238 1239 } 1239 1240
+4 -5
drivers/media/platform/samsung/exynos4-is/fimc-isp-video.c
··· 312 312 is_singular_file = v4l2_fh_is_singular_file(file); 313 313 314 314 if (is_singular_file && ivc->streaming) { 315 - media_pipeline_stop(entity); 315 + video_device_pipeline_stop(&ivc->ve.vdev); 316 316 ivc->streaming = 0; 317 317 } 318 318 ··· 490 490 { 491 491 struct fimc_isp *isp = video_drvdata(file); 492 492 struct exynos_video_entity *ve = &isp->video_capture.ve; 493 - struct media_entity *me = &ve->vdev.entity; 494 493 int ret; 495 494 496 - ret = media_pipeline_start(me, &ve->pipe->mp); 495 + ret = video_device_pipeline_start(&ve->vdev, &ve->pipe->mp); 497 496 if (ret < 0) 498 497 return ret; 499 498 ··· 507 508 isp->video_capture.streaming = 1; 508 509 return 0; 509 510 p_stop: 510 - media_pipeline_stop(me); 511 + video_device_pipeline_stop(&ve->vdev); 511 512 return ret; 512 513 } 513 514 ··· 522 523 if (ret < 0) 523 524 return ret; 524 525 525 - media_pipeline_stop(&video->ve.vdev.entity); 526 + video_device_pipeline_stop(&video->ve.vdev); 526 527 video->streaming = 0; 527 528 return 0; 528 529 }
+4 -5
drivers/media/platform/samsung/exynos4-is/fimc-lite.c
··· 516 516 if (v4l2_fh_is_singular_file(file) && 517 517 atomic_read(&fimc->out_path) == FIMC_IO_DMA) { 518 518 if (fimc->streaming) { 519 - media_pipeline_stop(entity); 519 + video_device_pipeline_stop(&fimc->ve.vdev); 520 520 fimc->streaming = false; 521 521 } 522 522 fimc_lite_stop_capture(fimc, false); ··· 812 812 enum v4l2_buf_type type) 813 813 { 814 814 struct fimc_lite *fimc = video_drvdata(file); 815 - struct media_entity *entity = &fimc->ve.vdev.entity; 816 815 int ret; 817 816 818 817 if (fimc_lite_active(fimc)) 819 818 return -EBUSY; 820 819 821 - ret = media_pipeline_start(entity, &fimc->ve.pipe->mp); 820 + ret = video_device_pipeline_start(&fimc->ve.vdev, &fimc->ve.pipe->mp); 822 821 if (ret < 0) 823 822 return ret; 824 823 ··· 834 835 } 835 836 836 837 err_p_stop: 837 - media_pipeline_stop(entity); 838 + video_device_pipeline_stop(&fimc->ve.vdev); 838 839 return 0; 839 840 } 840 841 ··· 848 849 if (ret < 0) 849 850 return ret; 850 851 851 - media_pipeline_stop(&fimc->ve.vdev.entity); 852 + video_device_pipeline_stop(&fimc->ve.vdev); 852 853 fimc->streaming = false; 853 854 return 0; 854 855 }
+3 -3
drivers/media/platform/samsung/s3c-camif/camif-capture.c
··· 848 848 if (s3c_vp_active(vp)) 849 849 return 0; 850 850 851 - ret = media_pipeline_start(sensor, camif->m_pipeline); 851 + ret = media_pipeline_start(sensor->pads, camif->m_pipeline); 852 852 if (ret < 0) 853 853 return ret; 854 854 855 855 ret = camif_pipeline_validate(camif); 856 856 if (ret < 0) { 857 - media_pipeline_stop(sensor); 857 + media_pipeline_stop(sensor->pads); 858 858 return ret; 859 859 } 860 860 ··· 878 878 879 879 ret = vb2_streamoff(&vp->vb_queue, type); 880 880 if (ret == 0) 881 - media_pipeline_stop(&camif->sensor.sd->entity); 881 + media_pipeline_stop(camif->sensor.sd->entity.pads); 882 882 return ret; 883 883 } 884 884
+3 -3
drivers/media/platform/st/stm32/stm32-dcmi.c
··· 751 751 goto err_unlocked; 752 752 } 753 753 754 - ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); 754 + ret = video_device_pipeline_start(dcmi->vdev, &dcmi->pipeline); 755 755 if (ret < 0) { 756 756 dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n", 757 757 __func__, ret); ··· 865 865 dcmi_pipeline_stop(dcmi); 866 866 867 867 err_media_pipeline_stop: 868 - media_pipeline_stop(&dcmi->vdev->entity); 868 + video_device_pipeline_stop(dcmi->vdev); 869 869 870 870 err_pm_put: 871 871 pm_runtime_put(dcmi->dev); ··· 892 892 893 893 dcmi_pipeline_stop(dcmi); 894 894 895 - media_pipeline_stop(&dcmi->vdev->entity); 895 + video_device_pipeline_stop(dcmi->vdev); 896 896 897 897 spin_lock_irq(&dcmi->irqlock); 898 898
+1 -1
drivers/media/platform/sunxi/sun4i-csi/Kconfig
··· 3 3 config VIDEO_SUN4I_CSI 4 4 tristate "Allwinner A10 CMOS Sensor Interface Support" 5 5 depends on V4L_PLATFORM_DRIVERS 6 - depends on VIDEO_DEV && COMMON_CLK && HAS_DMA 6 + depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA 7 7 depends on ARCH_SUNXI || COMPILE_TEST 8 8 select MEDIA_CONTROLLER 9 9 select VIDEO_V4L2_SUBDEV_API
+3 -3
drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
··· 266 266 goto err_clear_dma_queue; 267 267 } 268 268 269 - ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe); 269 + ret = video_device_pipeline_alloc_start(&csi->vdev); 270 270 if (ret < 0) 271 271 goto err_free_scratch_buffer; 272 272 ··· 330 330 sun4i_csi_capture_stop(csi); 331 331 332 332 err_disable_pipeline: 333 - media_pipeline_stop(&csi->vdev.entity); 333 + video_device_pipeline_stop(&csi->vdev); 334 334 335 335 err_free_scratch_buffer: 336 336 dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, ··· 359 359 return_all_buffers(csi, VB2_BUF_STATE_ERROR); 360 360 spin_unlock_irqrestore(&csi->qlock, flags); 361 361 362 - media_pipeline_stop(&csi->vdev.entity); 362 + video_device_pipeline_stop(&csi->vdev); 363 363 364 364 dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, 365 365 csi->scratch.paddr);
+7 -5
drivers/media/platform/sunxi/sun6i-csi/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config VIDEO_SUN6I_CSI 3 - tristate "Allwinner V3s Camera Sensor Interface driver" 4 - depends on V4L_PLATFORM_DRIVERS 5 - depends on VIDEO_DEV && COMMON_CLK && HAS_DMA 3 + tristate "Allwinner A31 Camera Sensor Interface (CSI) Driver" 4 + depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV 6 5 depends on ARCH_SUNXI || COMPILE_TEST 6 + depends on PM && COMMON_CLK && RESET_CONTROLLER && HAS_DMA 7 7 select MEDIA_CONTROLLER 8 8 select VIDEO_V4L2_SUBDEV_API 9 9 select VIDEOBUF2_DMA_CONTIG 10 - select REGMAP_MMIO 11 10 select V4L2_FWNODE 11 + select REGMAP_MMIO 12 12 help 13 - Support for the Allwinner Camera Sensor Interface Controller on V3s. 13 + Support for the Allwinner A31 Camera Sensor Interface (CSI) 14 + controller, also found on other platforms such as the A83T, H3, 15 + V3/V3s or A64.
+348 -248
drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
··· 23 23 #include <linux/sched.h> 24 24 #include <linux/sizes.h> 25 25 #include <linux/slab.h> 26 + #include <media/v4l2-mc.h> 26 27 27 28 #include "sun6i_csi.h" 28 29 #include "sun6i_csi_reg.h" 29 30 30 - #define MODULE_NAME "sun6i-csi" 31 - 32 - struct sun6i_csi_dev { 33 - struct sun6i_csi csi; 34 - struct device *dev; 35 - 36 - struct regmap *regmap; 37 - struct clk *clk_mod; 38 - struct clk *clk_ram; 39 - struct reset_control *rstc_bus; 40 - 41 - int planar_offset[3]; 42 - }; 43 - 44 - static inline struct sun6i_csi_dev *sun6i_csi_to_dev(struct sun6i_csi *csi) 45 - { 46 - return container_of(csi, struct sun6i_csi_dev, csi); 47 - } 31 + /* Helpers */ 48 32 49 33 /* TODO add 10&12 bit YUV, RGB support */ 50 - bool sun6i_csi_is_format_supported(struct sun6i_csi *csi, 34 + bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev, 51 35 u32 pixformat, u32 mbus_code) 52 36 { 53 - struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); 37 + struct sun6i_csi_v4l2 *v4l2 = &csi_dev->v4l2; 54 38 55 39 /* 56 40 * Some video receivers have the ability to be compatible with 57 41 * 8bit and 16bit bus width. 58 42 * Identify the media bus format from device tree. 59 43 */ 60 - if ((sdev->csi.v4l2_ep.bus_type == V4L2_MBUS_PARALLEL 61 - || sdev->csi.v4l2_ep.bus_type == V4L2_MBUS_BT656) 62 - && sdev->csi.v4l2_ep.bus.parallel.bus_width == 16) { 44 + if ((v4l2->v4l2_ep.bus_type == V4L2_MBUS_PARALLEL 45 + || v4l2->v4l2_ep.bus_type == V4L2_MBUS_BT656) 46 + && v4l2->v4l2_ep.bus.parallel.bus_width == 16) { 63 47 switch (pixformat) { 64 48 case V4L2_PIX_FMT_NV12_16L16: 65 49 case V4L2_PIX_FMT_NV12: ··· 60 76 case MEDIA_BUS_FMT_YVYU8_1X16: 61 77 return true; 62 78 default: 63 - dev_dbg(sdev->dev, "Unsupported mbus code: 0x%x\n", 79 + dev_dbg(csi_dev->dev, 80 + "Unsupported mbus code: 0x%x\n", 64 81 mbus_code); 65 82 break; 66 83 } 67 84 break; 68 85 default: 69 - dev_dbg(sdev->dev, "Unsupported pixformat: 0x%x\n", 86 + dev_dbg(csi_dev->dev, "Unsupported pixformat: 0x%x\n", 70 87 pixformat); 71 88 break; 72 89 } ··· 124 139 case MEDIA_BUS_FMT_YVYU8_2X8: 125 140 return true; 126 141 default: 127 - dev_dbg(sdev->dev, "Unsupported mbus code: 0x%x\n", 142 + dev_dbg(csi_dev->dev, "Unsupported mbus code: 0x%x\n", 128 143 mbus_code); 129 144 break; 130 145 } ··· 139 154 return (mbus_code == MEDIA_BUS_FMT_JPEG_1X8); 140 155 141 156 default: 142 - dev_dbg(sdev->dev, "Unsupported pixformat: 0x%x\n", pixformat); 157 + dev_dbg(csi_dev->dev, "Unsupported pixformat: 0x%x\n", 158 + pixformat); 143 159 break; 144 160 } 145 161 146 162 return false; 147 163 } 148 164 149 - int sun6i_csi_set_power(struct sun6i_csi *csi, bool enable) 165 + int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable) 150 166 { 151 - struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); 152 - struct device *dev = sdev->dev; 153 - struct regmap *regmap = sdev->regmap; 167 + struct device *dev = csi_dev->dev; 168 + struct regmap *regmap = csi_dev->regmap; 154 169 int ret; 155 170 156 171 if (!enable) { 157 172 regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, 0); 173 + pm_runtime_put(dev); 158 174 159 - clk_disable_unprepare(sdev->clk_ram); 160 - if (of_device_is_compatible(dev->of_node, 161 - "allwinner,sun50i-a64-csi")) 162 - clk_rate_exclusive_put(sdev->clk_mod); 163 - clk_disable_unprepare(sdev->clk_mod); 164 - reset_control_assert(sdev->rstc_bus); 165 175 return 0; 166 176 } 167 177 168 - ret = clk_prepare_enable(sdev->clk_mod); 169 - if (ret) { 170 - dev_err(sdev->dev, "Enable csi clk err %d\n", ret); 178 + ret = pm_runtime_resume_and_get(dev); 179 + if (ret < 0) 171 180 return ret; 172 - } 173 - 174 - if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi")) 175 - clk_set_rate_exclusive(sdev->clk_mod, 300000000); 176 - 177 - ret = clk_prepare_enable(sdev->clk_ram); 178 - if (ret) { 179 - dev_err(sdev->dev, "Enable clk_dram_csi clk err %d\n", ret); 180 - goto clk_mod_disable; 181 - } 182 - 183 - ret = reset_control_deassert(sdev->rstc_bus); 184 - if (ret) { 185 - dev_err(sdev->dev, "reset err %d\n", ret); 186 - goto clk_ram_disable; 187 - } 188 181 189 182 regmap_update_bits(regmap, CSI_EN_REG, CSI_EN_CSI_EN, CSI_EN_CSI_EN); 190 183 191 184 return 0; 192 - 193 - clk_ram_disable: 194 - clk_disable_unprepare(sdev->clk_ram); 195 - clk_mod_disable: 196 - if (of_device_is_compatible(dev->of_node, "allwinner,sun50i-a64-csi")) 197 - clk_rate_exclusive_put(sdev->clk_mod); 198 - clk_disable_unprepare(sdev->clk_mod); 199 - return ret; 200 185 } 201 186 202 - static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_dev *sdev, 187 + static enum csi_input_fmt get_csi_input_format(struct sun6i_csi_device *csi_dev, 203 188 u32 mbus_code, u32 pixformat) 204 189 { 205 190 /* non-YUV */ ··· 187 232 } 188 233 189 234 /* not support YUV420 input format yet */ 190 - dev_dbg(sdev->dev, "Select YUV422 as default input format of CSI.\n"); 235 + dev_dbg(csi_dev->dev, "Select YUV422 as default input format of CSI.\n"); 191 236 return CSI_INPUT_FORMAT_YUV422; 192 237 } 193 238 194 - static enum csi_output_fmt get_csi_output_format(struct sun6i_csi_dev *sdev, 195 - u32 pixformat, u32 field) 239 + static enum csi_output_fmt 240 + get_csi_output_format(struct sun6i_csi_device *csi_dev, u32 pixformat, 241 + u32 field) 196 242 { 197 243 bool buf_interlaced = false; 198 244 ··· 252 296 return buf_interlaced ? CSI_FRAME_RAW_8 : CSI_FIELD_RAW_8; 253 297 254 298 default: 255 - dev_warn(sdev->dev, "Unsupported pixformat: 0x%x\n", pixformat); 299 + dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x\n", pixformat); 256 300 break; 257 301 } 258 302 259 303 return CSI_FIELD_RAW_8; 260 304 } 261 305 262 - static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_dev *sdev, 306 + static enum csi_input_seq get_csi_input_seq(struct sun6i_csi_device *csi_dev, 263 307 u32 mbus_code, u32 pixformat) 264 308 { 265 309 /* Input sequence does not apply to non-YUV formats */ ··· 286 330 case MEDIA_BUS_FMT_YVYU8_2X8: 287 331 return CSI_INPUT_SEQ_YVYU; 288 332 default: 289 - dev_warn(sdev->dev, "Unsupported mbus code: 0x%x\n", 333 + dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", 290 334 mbus_code); 291 335 break; 292 336 } ··· 308 352 case MEDIA_BUS_FMT_YVYU8_2X8: 309 353 return CSI_INPUT_SEQ_YUYV; 310 354 default: 311 - dev_warn(sdev->dev, "Unsupported mbus code: 0x%x\n", 355 + dev_warn(csi_dev->dev, "Unsupported mbus code: 0x%x\n", 312 356 mbus_code); 313 357 break; 314 358 } ··· 318 362 return CSI_INPUT_SEQ_YUYV; 319 363 320 364 default: 321 - dev_warn(sdev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", 365 + dev_warn(csi_dev->dev, "Unsupported pixformat: 0x%x, defaulting to YUYV\n", 322 366 pixformat); 323 367 break; 324 368 } ··· 326 370 return CSI_INPUT_SEQ_YUYV; 327 371 } 328 372 329 - static void sun6i_csi_setup_bus(struct sun6i_csi_dev *sdev) 373 + static void sun6i_csi_setup_bus(struct sun6i_csi_device *csi_dev) 330 374 { 331 - struct v4l2_fwnode_endpoint *endpoint = &sdev->csi.v4l2_ep; 332 - struct sun6i_csi *csi = &sdev->csi; 375 + struct v4l2_fwnode_endpoint *endpoint = &csi_dev->v4l2.v4l2_ep; 376 + struct sun6i_csi_config *config = &csi_dev->config; 333 377 unsigned char bus_width; 334 378 u32 flags; 335 379 u32 cfg; 336 380 bool input_interlaced = false; 337 381 338 - if (csi->config.field == V4L2_FIELD_INTERLACED 339 - || csi->config.field == V4L2_FIELD_INTERLACED_TB 340 - || csi->config.field == V4L2_FIELD_INTERLACED_BT) 382 + if (config->field == V4L2_FIELD_INTERLACED 383 + || config->field == V4L2_FIELD_INTERLACED_TB 384 + || config->field == V4L2_FIELD_INTERLACED_BT) 341 385 input_interlaced = true; 342 386 343 387 bus_width = endpoint->bus.parallel.bus_width; 344 388 345 - regmap_read(sdev->regmap, CSI_IF_CFG_REG, &cfg); 389 + regmap_read(csi_dev->regmap, CSI_IF_CFG_REG, &cfg); 346 390 347 391 cfg &= ~(CSI_IF_CFG_CSI_IF_MASK | CSI_IF_CFG_MIPI_IF_MASK | 348 392 CSI_IF_CFG_IF_DATA_WIDTH_MASK | ··· 390 434 cfg |= CSI_IF_CFG_CLK_POL_FALLING_EDGE; 391 435 break; 392 436 default: 393 - dev_warn(sdev->dev, "Unsupported bus type: %d\n", 437 + dev_warn(csi_dev->dev, "Unsupported bus type: %d\n", 394 438 endpoint->bus_type); 395 439 break; 396 440 } ··· 408 452 case 16: /* No need to configure DATA_WIDTH for 16bit */ 409 453 break; 410 454 default: 411 - dev_warn(sdev->dev, "Unsupported bus width: %u\n", bus_width); 455 + dev_warn(csi_dev->dev, "Unsupported bus width: %u\n", bus_width); 412 456 break; 413 457 } 414 458 415 - regmap_write(sdev->regmap, CSI_IF_CFG_REG, cfg); 459 + regmap_write(csi_dev->regmap, CSI_IF_CFG_REG, cfg); 416 460 } 417 461 418 - static void sun6i_csi_set_format(struct sun6i_csi_dev *sdev) 462 + static void sun6i_csi_set_format(struct sun6i_csi_device *csi_dev) 419 463 { 420 - struct sun6i_csi *csi = &sdev->csi; 464 + struct sun6i_csi_config *config = &csi_dev->config; 421 465 u32 cfg; 422 466 u32 val; 423 467 424 - regmap_read(sdev->regmap, CSI_CH_CFG_REG, &cfg); 468 + regmap_read(csi_dev->regmap, CSI_CH_CFG_REG, &cfg); 425 469 426 470 cfg &= ~(CSI_CH_CFG_INPUT_FMT_MASK | 427 471 CSI_CH_CFG_OUTPUT_FMT_MASK | CSI_CH_CFG_VFLIP_EN | 428 472 CSI_CH_CFG_HFLIP_EN | CSI_CH_CFG_FIELD_SEL_MASK | 429 473 CSI_CH_CFG_INPUT_SEQ_MASK); 430 474 431 - val = get_csi_input_format(sdev, csi->config.code, 432 - csi->config.pixelformat); 475 + val = get_csi_input_format(csi_dev, config->code, 476 + config->pixelformat); 433 477 cfg |= CSI_CH_CFG_INPUT_FMT(val); 434 478 435 - val = get_csi_output_format(sdev, csi->config.pixelformat, 436 - csi->config.field); 479 + val = get_csi_output_format(csi_dev, config->pixelformat, 480 + config->field); 437 481 cfg |= CSI_CH_CFG_OUTPUT_FMT(val); 438 482 439 - val = get_csi_input_seq(sdev, csi->config.code, 440 - csi->config.pixelformat); 483 + val = get_csi_input_seq(csi_dev, config->code, 484 + config->pixelformat); 441 485 cfg |= CSI_CH_CFG_INPUT_SEQ(val); 442 486 443 - if (csi->config.field == V4L2_FIELD_TOP) 487 + if (config->field == V4L2_FIELD_TOP) 444 488 cfg |= CSI_CH_CFG_FIELD_SEL_FIELD0; 445 - else if (csi->config.field == V4L2_FIELD_BOTTOM) 489 + else if (config->field == V4L2_FIELD_BOTTOM) 446 490 cfg |= CSI_CH_CFG_FIELD_SEL_FIELD1; 447 491 else 448 492 cfg |= CSI_CH_CFG_FIELD_SEL_BOTH; 449 493 450 - regmap_write(sdev->regmap, CSI_CH_CFG_REG, cfg); 494 + regmap_write(csi_dev->regmap, CSI_CH_CFG_REG, cfg); 451 495 } 452 496 453 - static void sun6i_csi_set_window(struct sun6i_csi_dev *sdev) 497 + static void sun6i_csi_set_window(struct sun6i_csi_device *csi_dev) 454 498 { 455 - struct sun6i_csi_config *config = &sdev->csi.config; 499 + struct sun6i_csi_config *config = &csi_dev->config; 456 500 u32 bytesperline_y; 457 501 u32 bytesperline_c; 458 - int *planar_offset = sdev->planar_offset; 502 + int *planar_offset = csi_dev->planar_offset; 459 503 u32 width = config->width; 460 504 u32 height = config->height; 461 505 u32 hor_len = width; ··· 465 509 case V4L2_PIX_FMT_YVYU: 466 510 case V4L2_PIX_FMT_UYVY: 467 511 case V4L2_PIX_FMT_VYUY: 468 - dev_dbg(sdev->dev, 512 + dev_dbg(csi_dev->dev, 469 513 "Horizontal length should be 2 times of width for packed YUV formats!\n"); 470 514 hor_len = width * 2; 471 515 break; ··· 473 517 break; 474 518 } 475 519 476 - regmap_write(sdev->regmap, CSI_CH_HSIZE_REG, 520 + regmap_write(csi_dev->regmap, CSI_CH_HSIZE_REG, 477 521 CSI_CH_HSIZE_HOR_LEN(hor_len) | 478 522 CSI_CH_HSIZE_HOR_START(0)); 479 - regmap_write(sdev->regmap, CSI_CH_VSIZE_REG, 523 + regmap_write(csi_dev->regmap, CSI_CH_VSIZE_REG, 480 524 CSI_CH_VSIZE_VER_LEN(height) | 481 525 CSI_CH_VSIZE_VER_START(0)); 482 526 ··· 508 552 bytesperline_c * height; 509 553 break; 510 554 default: /* raw */ 511 - dev_dbg(sdev->dev, 555 + dev_dbg(csi_dev->dev, 512 556 "Calculating pixelformat(0x%x)'s bytesperline as a packed format\n", 513 557 config->pixelformat); 514 558 bytesperline_y = (sun6i_csi_get_bpp(config->pixelformat) * ··· 519 563 break; 520 564 } 521 565 522 - regmap_write(sdev->regmap, CSI_CH_BUF_LEN_REG, 566 + regmap_write(csi_dev->regmap, CSI_CH_BUF_LEN_REG, 523 567 CSI_CH_BUF_LEN_BUF_LEN_C(bytesperline_c) | 524 568 CSI_CH_BUF_LEN_BUF_LEN_Y(bytesperline_y)); 525 569 } 526 570 527 - int sun6i_csi_update_config(struct sun6i_csi *csi, 571 + int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, 528 572 struct sun6i_csi_config *config) 529 573 { 530 - struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); 531 - 532 574 if (!config) 533 575 return -EINVAL; 534 576 535 - memcpy(&csi->config, config, sizeof(csi->config)); 577 + memcpy(&csi_dev->config, config, sizeof(csi_dev->config)); 536 578 537 - sun6i_csi_setup_bus(sdev); 538 - sun6i_csi_set_format(sdev); 539 - sun6i_csi_set_window(sdev); 579 + sun6i_csi_setup_bus(csi_dev); 580 + sun6i_csi_set_format(csi_dev); 581 + sun6i_csi_set_window(csi_dev); 540 582 541 583 return 0; 542 584 } 543 585 544 - void sun6i_csi_update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr) 586 + void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev, 587 + dma_addr_t addr) 545 588 { 546 - struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); 547 - 548 - regmap_write(sdev->regmap, CSI_CH_F0_BUFA_REG, 549 - (addr + sdev->planar_offset[0]) >> 2); 550 - if (sdev->planar_offset[1] != -1) 551 - regmap_write(sdev->regmap, CSI_CH_F1_BUFA_REG, 552 - (addr + sdev->planar_offset[1]) >> 2); 553 - if (sdev->planar_offset[2] != -1) 554 - regmap_write(sdev->regmap, CSI_CH_F2_BUFA_REG, 555 - (addr + sdev->planar_offset[2]) >> 2); 589 + regmap_write(csi_dev->regmap, CSI_CH_F0_BUFA_REG, 590 + (addr + csi_dev->planar_offset[0]) >> 2); 591 + if (csi_dev->planar_offset[1] != -1) 592 + regmap_write(csi_dev->regmap, CSI_CH_F1_BUFA_REG, 593 + (addr + csi_dev->planar_offset[1]) >> 2); 594 + if (csi_dev->planar_offset[2] != -1) 595 + regmap_write(csi_dev->regmap, CSI_CH_F2_BUFA_REG, 596 + (addr + csi_dev->planar_offset[2]) >> 2); 556 597 } 557 598 558 - void sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable) 599 + void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable) 559 600 { 560 - struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi); 561 - struct regmap *regmap = sdev->regmap; 601 + struct regmap *regmap = csi_dev->regmap; 562 602 563 603 if (!enable) { 564 604 regmap_update_bits(regmap, CSI_CAP_REG, CSI_CAP_CH0_VCAP_ON, 0); ··· 575 623 CSI_CAP_CH0_VCAP_ON); 576 624 } 577 625 578 - /* ----------------------------------------------------------------------------- 579 - * Media Controller and V4L2 580 - */ 581 - static int sun6i_csi_link_entity(struct sun6i_csi *csi, 626 + /* Media */ 627 + 628 + static const struct media_device_ops sun6i_csi_media_ops = { 629 + .link_notify = v4l2_pipeline_link_notify, 630 + }; 631 + 632 + /* V4L2 */ 633 + 634 + static int sun6i_csi_link_entity(struct sun6i_csi_device *csi_dev, 582 635 struct media_entity *entity, 583 636 struct fwnode_handle *fwnode) 584 637 { ··· 594 637 595 638 ret = media_entity_get_fwnode_pad(entity, fwnode, MEDIA_PAD_FL_SOURCE); 596 639 if (ret < 0) { 597 - dev_err(csi->dev, "%s: no source pad in external entity %s\n", 598 - __func__, entity->name); 640 + dev_err(csi_dev->dev, 641 + "%s: no source pad in external entity %s\n", __func__, 642 + entity->name); 599 643 return -EINVAL; 600 644 } 601 645 602 646 src_pad_index = ret; 603 647 604 - sink = &csi->video.vdev.entity; 605 - sink_pad = &csi->video.pad; 648 + sink = &csi_dev->video.video_dev.entity; 649 + sink_pad = &csi_dev->video.pad; 606 650 607 - dev_dbg(csi->dev, "creating %s:%u -> %s:%u link\n", 651 + dev_dbg(csi_dev->dev, "creating %s:%u -> %s:%u link\n", 608 652 entity->name, src_pad_index, sink->name, sink_pad->index); 609 653 ret = media_create_pad_link(entity, src_pad_index, sink, 610 654 sink_pad->index, 611 655 MEDIA_LNK_FL_ENABLED | 612 656 MEDIA_LNK_FL_IMMUTABLE); 613 657 if (ret < 0) { 614 - dev_err(csi->dev, "failed to create %s:%u -> %s:%u link\n", 658 + dev_err(csi_dev->dev, "failed to create %s:%u -> %s:%u link\n", 615 659 entity->name, src_pad_index, 616 660 sink->name, sink_pad->index); 617 661 return ret; ··· 623 665 624 666 static int sun6i_subdev_notify_complete(struct v4l2_async_notifier *notifier) 625 667 { 626 - struct sun6i_csi *csi = container_of(notifier, struct sun6i_csi, 627 - notifier); 628 - struct v4l2_device *v4l2_dev = &csi->v4l2_dev; 668 + struct sun6i_csi_device *csi_dev = 669 + container_of(notifier, struct sun6i_csi_device, 670 + v4l2.notifier); 671 + struct sun6i_csi_v4l2 *v4l2 = &csi_dev->v4l2; 672 + struct v4l2_device *v4l2_dev = &v4l2->v4l2_dev; 629 673 struct v4l2_subdev *sd; 630 674 int ret; 631 675 632 - dev_dbg(csi->dev, "notify complete, all subdevs registered\n"); 676 + dev_dbg(csi_dev->dev, "notify complete, all subdevs registered\n"); 633 677 634 678 sd = list_first_entry(&v4l2_dev->subdevs, struct v4l2_subdev, list); 635 679 if (!sd) 636 680 return -EINVAL; 637 681 638 - ret = sun6i_csi_link_entity(csi, &sd->entity, sd->fwnode); 682 + ret = sun6i_csi_link_entity(csi_dev, &sd->entity, sd->fwnode); 639 683 if (ret < 0) 640 684 return ret; 641 685 642 - ret = v4l2_device_register_subdev_nodes(&csi->v4l2_dev); 686 + ret = v4l2_device_register_subdev_nodes(v4l2_dev); 643 687 if (ret < 0) 644 688 return ret; 645 689 646 - return media_device_register(&csi->media_dev); 690 + return 0; 647 691 } 648 692 649 693 static const struct v4l2_async_notifier_operations sun6i_csi_async_ops = { ··· 656 696 struct v4l2_fwnode_endpoint *vep, 657 697 struct v4l2_async_subdev *asd) 658 698 { 659 - struct sun6i_csi *csi = dev_get_drvdata(dev); 699 + struct sun6i_csi_device *csi_dev = dev_get_drvdata(dev); 660 700 661 701 if (vep->base.port || vep->base.id) { 662 702 dev_warn(dev, "Only support a single port with one endpoint\n"); ··· 666 706 switch (vep->bus_type) { 667 707 case V4L2_MBUS_PARALLEL: 668 708 case V4L2_MBUS_BT656: 669 - csi->v4l2_ep = *vep; 709 + csi_dev->v4l2.v4l2_ep = *vep; 670 710 return 0; 671 711 default: 672 712 dev_err(dev, "Unsupported media bus type\n"); ··· 674 714 } 675 715 } 676 716 677 - static void sun6i_csi_v4l2_cleanup(struct sun6i_csi *csi) 717 + static int sun6i_csi_v4l2_setup(struct sun6i_csi_device *csi_dev) 678 718 { 679 - media_device_unregister(&csi->media_dev); 680 - v4l2_async_nf_unregister(&csi->notifier); 681 - v4l2_async_nf_cleanup(&csi->notifier); 682 - sun6i_video_cleanup(&csi->video); 683 - v4l2_device_unregister(&csi->v4l2_dev); 684 - v4l2_ctrl_handler_free(&csi->ctrl_handler); 685 - media_device_cleanup(&csi->media_dev); 686 - } 687 - 688 - static int sun6i_csi_v4l2_init(struct sun6i_csi *csi) 689 - { 719 + struct sun6i_csi_v4l2 *v4l2 = &csi_dev->v4l2; 720 + struct media_device *media_dev = &v4l2->media_dev; 721 + struct v4l2_device *v4l2_dev = &v4l2->v4l2_dev; 722 + struct v4l2_async_notifier *notifier = &v4l2->notifier; 723 + struct device *dev = csi_dev->dev; 690 724 int ret; 691 725 692 - csi->media_dev.dev = csi->dev; 693 - strscpy(csi->media_dev.model, "Allwinner Video Capture Device", 694 - sizeof(csi->media_dev.model)); 695 - csi->media_dev.hw_revision = 0; 726 + /* Media Device */ 696 727 697 - media_device_init(&csi->media_dev); 698 - v4l2_async_nf_init(&csi->notifier); 728 + strscpy(media_dev->model, SUN6I_CSI_DESCRIPTION, 729 + sizeof(media_dev->model)); 730 + media_dev->hw_revision = 0; 731 + media_dev->ops = &sun6i_csi_media_ops; 732 + media_dev->dev = dev; 699 733 700 - ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 0); 734 + media_device_init(media_dev); 735 + 736 + ret = media_device_register(media_dev); 701 737 if (ret) { 702 - dev_err(csi->dev, "V4L2 controls handler init failed (%d)\n", 703 - ret); 704 - goto clean_media; 738 + dev_err(dev, "failed to register media device: %d\n", ret); 739 + goto error_media; 705 740 } 706 741 707 - csi->v4l2_dev.mdev = &csi->media_dev; 708 - csi->v4l2_dev.ctrl_handler = &csi->ctrl_handler; 709 - ret = v4l2_device_register(csi->dev, &csi->v4l2_dev); 742 + /* V4L2 Device */ 743 + 744 + v4l2_dev->mdev = media_dev; 745 + 746 + ret = v4l2_device_register(dev, v4l2_dev); 710 747 if (ret) { 711 - dev_err(csi->dev, "V4L2 device registration failed (%d)\n", 712 - ret); 713 - goto free_ctrl; 748 + dev_err(dev, "failed to register v4l2 device: %d\n", ret); 749 + goto error_media; 714 750 } 715 751 716 - ret = sun6i_video_init(&csi->video, csi, "sun6i-csi"); 752 + /* Video */ 753 + 754 + ret = sun6i_video_setup(csi_dev); 717 755 if (ret) 718 - goto unreg_v4l2; 756 + goto error_v4l2_device; 719 757 720 - ret = v4l2_async_nf_parse_fwnode_endpoints(csi->dev, 721 - &csi->notifier, 758 + /* V4L2 Async */ 759 + 760 + v4l2_async_nf_init(notifier); 761 + notifier->ops = &sun6i_csi_async_ops; 762 + 763 + ret = v4l2_async_nf_parse_fwnode_endpoints(dev, notifier, 722 764 sizeof(struct 723 765 v4l2_async_subdev), 724 766 sun6i_csi_fwnode_parse); 725 767 if (ret) 726 - goto clean_video; 768 + goto error_video; 727 769 728 - csi->notifier.ops = &sun6i_csi_async_ops; 729 - 730 - ret = v4l2_async_nf_register(&csi->v4l2_dev, &csi->notifier); 770 + ret = v4l2_async_nf_register(v4l2_dev, notifier); 731 771 if (ret) { 732 - dev_err(csi->dev, "notifier registration failed\n"); 733 - goto clean_video; 772 + dev_err(dev, "failed to register v4l2 async notifier: %d\n", 773 + ret); 774 + goto error_v4l2_async_notifier; 734 775 } 735 776 736 777 return 0; 737 778 738 - clean_video: 739 - sun6i_video_cleanup(&csi->video); 740 - unreg_v4l2: 741 - v4l2_device_unregister(&csi->v4l2_dev); 742 - free_ctrl: 743 - v4l2_ctrl_handler_free(&csi->ctrl_handler); 744 - clean_media: 745 - v4l2_async_nf_cleanup(&csi->notifier); 746 - media_device_cleanup(&csi->media_dev); 779 + error_v4l2_async_notifier: 780 + v4l2_async_nf_cleanup(notifier); 781 + 782 + error_video: 783 + sun6i_video_cleanup(csi_dev); 784 + 785 + error_v4l2_device: 786 + v4l2_device_unregister(&v4l2->v4l2_dev); 787 + 788 + error_media: 789 + media_device_unregister(media_dev); 790 + media_device_cleanup(media_dev); 747 791 748 792 return ret; 749 793 } 750 794 751 - /* ----------------------------------------------------------------------------- 752 - * Resources and IRQ 753 - */ 754 - static irqreturn_t sun6i_csi_isr(int irq, void *dev_id) 795 + static void sun6i_csi_v4l2_cleanup(struct sun6i_csi_device *csi_dev) 755 796 { 756 - struct sun6i_csi_dev *sdev = (struct sun6i_csi_dev *)dev_id; 757 - struct regmap *regmap = sdev->regmap; 797 + struct sun6i_csi_v4l2 *v4l2 = &csi_dev->v4l2; 798 + 799 + media_device_unregister(&v4l2->media_dev); 800 + v4l2_async_nf_unregister(&v4l2->notifier); 801 + v4l2_async_nf_cleanup(&v4l2->notifier); 802 + sun6i_video_cleanup(csi_dev); 803 + v4l2_device_unregister(&v4l2->v4l2_dev); 804 + media_device_cleanup(&v4l2->media_dev); 805 + } 806 + 807 + /* Platform */ 808 + 809 + static irqreturn_t sun6i_csi_interrupt(int irq, void *private) 810 + { 811 + struct sun6i_csi_device *csi_dev = private; 812 + struct regmap *regmap = csi_dev->regmap; 758 813 u32 status; 759 814 760 815 regmap_read(regmap, CSI_CH_INT_STA_REG, &status); ··· 789 814 } 790 815 791 816 if (status & CSI_CH_INT_STA_FD_PD) 792 - sun6i_video_frame_done(&sdev->csi.video); 817 + sun6i_video_frame_done(csi_dev); 793 818 794 819 regmap_write(regmap, CSI_CH_INT_STA_REG, status); 795 820 796 821 return IRQ_HANDLED; 797 822 } 823 + 824 + static int sun6i_csi_suspend(struct device *dev) 825 + { 826 + struct sun6i_csi_device *csi_dev = dev_get_drvdata(dev); 827 + 828 + reset_control_assert(csi_dev->reset); 829 + clk_disable_unprepare(csi_dev->clock_ram); 830 + clk_disable_unprepare(csi_dev->clock_mod); 831 + 832 + return 0; 833 + } 834 + 835 + static int sun6i_csi_resume(struct device *dev) 836 + { 837 + struct sun6i_csi_device *csi_dev = dev_get_drvdata(dev); 838 + int ret; 839 + 840 + ret = reset_control_deassert(csi_dev->reset); 841 + if (ret) { 842 + dev_err(dev, "failed to deassert reset\n"); 843 + return ret; 844 + } 845 + 846 + ret = clk_prepare_enable(csi_dev->clock_mod); 847 + if (ret) { 848 + dev_err(dev, "failed to enable module clock\n"); 849 + goto error_reset; 850 + } 851 + 852 + ret = clk_prepare_enable(csi_dev->clock_ram); 853 + if (ret) { 854 + dev_err(dev, "failed to enable ram clock\n"); 855 + goto error_clock_mod; 856 + } 857 + 858 + return 0; 859 + 860 + error_clock_mod: 861 + clk_disable_unprepare(csi_dev->clock_mod); 862 + 863 + error_reset: 864 + reset_control_assert(csi_dev->reset); 865 + 866 + return ret; 867 + } 868 + 869 + static const struct dev_pm_ops sun6i_csi_pm_ops = { 870 + .runtime_suspend = sun6i_csi_suspend, 871 + .runtime_resume = sun6i_csi_resume, 872 + }; 798 873 799 874 static const struct regmap_config sun6i_csi_regmap_config = { 800 875 .reg_bits = 32, ··· 853 828 .max_register = 0x9c, 854 829 }; 855 830 856 - static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, 857 - struct platform_device *pdev) 831 + static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev, 832 + struct platform_device *platform_dev) 858 833 { 834 + struct device *dev = csi_dev->dev; 835 + const struct sun6i_csi_variant *variant; 859 836 void __iomem *io_base; 860 837 int ret; 861 838 int irq; 862 839 863 - io_base = devm_platform_ioremap_resource(pdev, 0); 840 + variant = of_device_get_match_data(dev); 841 + if (!variant) 842 + return -EINVAL; 843 + 844 + /* Registers */ 845 + 846 + io_base = devm_platform_ioremap_resource(platform_dev, 0); 864 847 if (IS_ERR(io_base)) 865 848 return PTR_ERR(io_base); 866 849 867 - sdev->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", io_base, 868 - &sun6i_csi_regmap_config); 869 - if (IS_ERR(sdev->regmap)) { 870 - dev_err(&pdev->dev, "Failed to init register map\n"); 871 - return PTR_ERR(sdev->regmap); 850 + csi_dev->regmap = devm_regmap_init_mmio_clk(dev, "bus", io_base, 851 + &sun6i_csi_regmap_config); 852 + if (IS_ERR(csi_dev->regmap)) { 853 + dev_err(dev, "failed to init register map\n"); 854 + return PTR_ERR(csi_dev->regmap); 872 855 } 873 856 874 - sdev->clk_mod = devm_clk_get(&pdev->dev, "mod"); 875 - if (IS_ERR(sdev->clk_mod)) { 876 - dev_err(&pdev->dev, "Unable to acquire csi clock\n"); 877 - return PTR_ERR(sdev->clk_mod); 857 + /* Clocks */ 858 + 859 + csi_dev->clock_mod = devm_clk_get(dev, "mod"); 860 + if (IS_ERR(csi_dev->clock_mod)) { 861 + dev_err(dev, "failed to acquire module clock\n"); 862 + return PTR_ERR(csi_dev->clock_mod); 878 863 } 879 864 880 - sdev->clk_ram = devm_clk_get(&pdev->dev, "ram"); 881 - if (IS_ERR(sdev->clk_ram)) { 882 - dev_err(&pdev->dev, "Unable to acquire dram-csi clock\n"); 883 - return PTR_ERR(sdev->clk_ram); 865 + csi_dev->clock_ram = devm_clk_get(dev, "ram"); 866 + if (IS_ERR(csi_dev->clock_ram)) { 867 + dev_err(dev, "failed to acquire ram clock\n"); 868 + return PTR_ERR(csi_dev->clock_ram); 884 869 } 885 870 886 - sdev->rstc_bus = devm_reset_control_get_shared(&pdev->dev, NULL); 887 - if (IS_ERR(sdev->rstc_bus)) { 888 - dev_err(&pdev->dev, "Cannot get reset controller\n"); 889 - return PTR_ERR(sdev->rstc_bus); 890 - } 891 - 892 - irq = platform_get_irq(pdev, 0); 893 - if (irq < 0) 894 - return -ENXIO; 895 - 896 - ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, MODULE_NAME, 897 - sdev); 871 + ret = clk_set_rate_exclusive(csi_dev->clock_mod, 872 + variant->clock_mod_rate); 898 873 if (ret) { 899 - dev_err(&pdev->dev, "Cannot request csi IRQ\n"); 874 + dev_err(dev, "failed to set mod clock rate\n"); 900 875 return ret; 901 876 } 902 877 878 + /* Reset */ 879 + 880 + csi_dev->reset = devm_reset_control_get_shared(dev, NULL); 881 + if (IS_ERR(csi_dev->reset)) { 882 + dev_err(dev, "failed to acquire reset\n"); 883 + ret = PTR_ERR(csi_dev->reset); 884 + goto error_clock_rate_exclusive; 885 + } 886 + 887 + /* Interrupt */ 888 + 889 + irq = platform_get_irq(platform_dev, 0); 890 + if (irq < 0) { 891 + dev_err(dev, "failed to get interrupt\n"); 892 + ret = -ENXIO; 893 + goto error_clock_rate_exclusive; 894 + } 895 + 896 + ret = devm_request_irq(dev, irq, sun6i_csi_interrupt, 0, SUN6I_CSI_NAME, 897 + csi_dev); 898 + if (ret) { 899 + dev_err(dev, "failed to request interrupt\n"); 900 + goto error_clock_rate_exclusive; 901 + } 902 + 903 + /* Runtime PM */ 904 + 905 + pm_runtime_enable(dev); 906 + 903 907 return 0; 908 + 909 + error_clock_rate_exclusive: 910 + clk_rate_exclusive_put(csi_dev->clock_mod); 911 + 912 + return ret; 904 913 } 905 914 906 - static int sun6i_csi_probe(struct platform_device *pdev) 915 + static void sun6i_csi_resources_cleanup(struct sun6i_csi_device *csi_dev) 907 916 { 908 - struct sun6i_csi_dev *sdev; 917 + pm_runtime_disable(csi_dev->dev); 918 + clk_rate_exclusive_put(csi_dev->clock_mod); 919 + } 920 + 921 + static int sun6i_csi_probe(struct platform_device *platform_dev) 922 + { 923 + struct sun6i_csi_device *csi_dev; 924 + struct device *dev = &platform_dev->dev; 909 925 int ret; 910 926 911 - sdev = devm_kzalloc(&pdev->dev, sizeof(*sdev), GFP_KERNEL); 912 - if (!sdev) 927 + csi_dev = devm_kzalloc(dev, sizeof(*csi_dev), GFP_KERNEL); 928 + if (!csi_dev) 913 929 return -ENOMEM; 914 930 915 - sdev->dev = &pdev->dev; 931 + csi_dev->dev = &platform_dev->dev; 932 + platform_set_drvdata(platform_dev, csi_dev); 916 933 917 - ret = sun6i_csi_resource_request(sdev, pdev); 934 + ret = sun6i_csi_resources_setup(csi_dev, platform_dev); 918 935 if (ret) 919 936 return ret; 920 937 921 - platform_set_drvdata(pdev, sdev); 938 + ret = sun6i_csi_v4l2_setup(csi_dev); 939 + if (ret) 940 + goto error_resources; 922 941 923 - sdev->csi.dev = &pdev->dev; 924 - return sun6i_csi_v4l2_init(&sdev->csi); 942 + return 0; 943 + 944 + error_resources: 945 + sun6i_csi_resources_cleanup(csi_dev); 946 + 947 + return ret; 925 948 } 926 949 927 950 static int sun6i_csi_remove(struct platform_device *pdev) 928 951 { 929 - struct sun6i_csi_dev *sdev = platform_get_drvdata(pdev); 952 + struct sun6i_csi_device *csi_dev = platform_get_drvdata(pdev); 930 953 931 - sun6i_csi_v4l2_cleanup(&sdev->csi); 954 + sun6i_csi_v4l2_cleanup(csi_dev); 955 + sun6i_csi_resources_cleanup(csi_dev); 932 956 933 957 return 0; 934 958 } 935 959 960 + static const struct sun6i_csi_variant sun6i_a31_csi_variant = { 961 + .clock_mod_rate = 297000000, 962 + }; 963 + 964 + static const struct sun6i_csi_variant sun50i_a64_csi_variant = { 965 + .clock_mod_rate = 300000000, 966 + }; 967 + 936 968 static const struct of_device_id sun6i_csi_of_match[] = { 937 - { .compatible = "allwinner,sun6i-a31-csi", }, 938 - { .compatible = "allwinner,sun8i-a83t-csi", }, 939 - { .compatible = "allwinner,sun8i-h3-csi", }, 940 - { .compatible = "allwinner,sun8i-v3s-csi", }, 941 - { .compatible = "allwinner,sun50i-a64-csi", }, 969 + { 970 + .compatible = "allwinner,sun6i-a31-csi", 971 + .data = &sun6i_a31_csi_variant, 972 + }, 973 + { 974 + .compatible = "allwinner,sun8i-a83t-csi", 975 + .data = &sun6i_a31_csi_variant, 976 + }, 977 + { 978 + .compatible = "allwinner,sun8i-h3-csi", 979 + .data = &sun6i_a31_csi_variant, 980 + }, 981 + { 982 + .compatible = "allwinner,sun8i-v3s-csi", 983 + .data = &sun6i_a31_csi_variant, 984 + }, 985 + { 986 + .compatible = "allwinner,sun50i-a64-csi", 987 + .data = &sun50i_a64_csi_variant, 988 + }, 942 989 {}, 943 990 }; 991 + 944 992 MODULE_DEVICE_TABLE(of, sun6i_csi_of_match); 945 993 946 994 static struct platform_driver sun6i_csi_platform_driver = { 947 - .probe = sun6i_csi_probe, 948 - .remove = sun6i_csi_remove, 949 - .driver = { 950 - .name = MODULE_NAME, 951 - .of_match_table = of_match_ptr(sun6i_csi_of_match), 995 + .probe = sun6i_csi_probe, 996 + .remove = sun6i_csi_remove, 997 + .driver = { 998 + .name = SUN6I_CSI_NAME, 999 + .of_match_table = of_match_ptr(sun6i_csi_of_match), 1000 + .pm = &sun6i_csi_pm_ops, 952 1001 }, 953 1002 }; 1003 + 954 1004 module_platform_driver(sun6i_csi_platform_driver); 955 1005 956 - MODULE_DESCRIPTION("Allwinner V3s Camera Sensor Interface driver"); 1006 + MODULE_DESCRIPTION("Allwinner A31 Camera Sensor Interface driver"); 957 1007 MODULE_AUTHOR("Yong Deng <yong.deng@magewell.com>"); 958 1008 MODULE_LICENSE("GPL");
+46 -18
drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
··· 8 8 #ifndef __SUN6I_CSI_H__ 9 9 #define __SUN6I_CSI_H__ 10 10 11 - #include <media/v4l2-ctrls.h> 12 11 #include <media/v4l2-device.h> 13 12 #include <media/v4l2-fwnode.h> 13 + #include <media/videobuf2-v4l2.h> 14 14 15 15 #include "sun6i_video.h" 16 16 17 - struct sun6i_csi; 17 + #define SUN6I_CSI_NAME "sun6i-csi" 18 + #define SUN6I_CSI_DESCRIPTION "Allwinner A31 CSI Device" 19 + 20 + struct sun6i_csi_buffer { 21 + struct vb2_v4l2_buffer v4l2_buffer; 22 + struct list_head list; 23 + 24 + dma_addr_t dma_addr; 25 + bool queued_to_csi; 26 + }; 18 27 19 28 /** 20 29 * struct sun6i_csi_config - configs for sun6i csi ··· 41 32 u32 height; 42 33 }; 43 34 44 - struct sun6i_csi { 45 - struct device *dev; 46 - struct v4l2_ctrl_handler ctrl_handler; 35 + struct sun6i_csi_v4l2 { 47 36 struct v4l2_device v4l2_dev; 48 37 struct media_device media_dev; 49 38 50 39 struct v4l2_async_notifier notifier; 51 - 52 40 /* video port settings */ 53 41 struct v4l2_fwnode_endpoint v4l2_ep; 42 + }; 43 + 44 + struct sun6i_csi_device { 45 + struct device *dev; 54 46 55 47 struct sun6i_csi_config config; 56 - 48 + struct sun6i_csi_v4l2 v4l2; 57 49 struct sun6i_video video; 50 + 51 + struct regmap *regmap; 52 + struct clk *clock_mod; 53 + struct clk *clock_ram; 54 + struct reset_control *reset; 55 + 56 + int planar_offset[3]; 57 + }; 58 + 59 + struct sun6i_csi_variant { 60 + unsigned long clock_mod_rate; 58 61 }; 59 62 60 63 /** 61 64 * sun6i_csi_is_format_supported() - check if the format supported by csi 62 - * @csi: pointer to the csi 65 + * @csi_dev: pointer to the csi device 63 66 * @pixformat: v4l2 pixel format (V4L2_PIX_FMT_*) 64 67 * @mbus_code: media bus format code (MEDIA_BUS_FMT_*) 68 + * 69 + * Return: true if format is supported, false otherwise. 65 70 */ 66 - bool sun6i_csi_is_format_supported(struct sun6i_csi *csi, u32 pixformat, 67 - u32 mbus_code); 71 + bool sun6i_csi_is_format_supported(struct sun6i_csi_device *csi_dev, 72 + u32 pixformat, u32 mbus_code); 68 73 69 74 /** 70 75 * sun6i_csi_set_power() - power on/off the csi 71 - * @csi: pointer to the csi 76 + * @csi_dev: pointer to the csi device 72 77 * @enable: on/off 78 + * 79 + * Return: 0 if successful, error code otherwise. 73 80 */ 74 - int sun6i_csi_set_power(struct sun6i_csi *csi, bool enable); 81 + int sun6i_csi_set_power(struct sun6i_csi_device *csi_dev, bool enable); 75 82 76 83 /** 77 84 * sun6i_csi_update_config() - update the csi register settings 78 - * @csi: pointer to the csi 85 + * @csi_dev: pointer to the csi device 79 86 * @config: see struct sun6i_csi_config 87 + * 88 + * Return: 0 if successful, error code otherwise. 80 89 */ 81 - int sun6i_csi_update_config(struct sun6i_csi *csi, 90 + int sun6i_csi_update_config(struct sun6i_csi_device *csi_dev, 82 91 struct sun6i_csi_config *config); 83 92 84 93 /** 85 94 * sun6i_csi_update_buf_addr() - update the csi frame buffer address 86 - * @csi: pointer to the csi 95 + * @csi_dev: pointer to the csi device 87 96 * @addr: frame buffer's physical address 88 97 */ 89 - void sun6i_csi_update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr); 98 + void sun6i_csi_update_buf_addr(struct sun6i_csi_device *csi_dev, 99 + dma_addr_t addr); 90 100 91 101 /** 92 102 * sun6i_csi_set_stream() - start/stop csi streaming 93 - * @csi: pointer to the csi 103 + * @csi_dev: pointer to the csi device 94 104 * @enable: start/stop 95 105 */ 96 - void sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable); 106 + void sun6i_csi_set_stream(struct sun6i_csi_device *csi_dev, bool enable); 97 107 98 108 /* get bpp form v4l2 pixformat */ 99 109 static inline int sun6i_csi_get_bpp(unsigned int pixformat)
+322 -274
drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c
··· 23 23 #define MAX_WIDTH (4800) 24 24 #define MAX_HEIGHT (4800) 25 25 26 - struct sun6i_csi_buffer { 27 - struct vb2_v4l2_buffer vb; 28 - struct list_head list; 26 + /* Helpers */ 29 27 30 - dma_addr_t dma_addr; 31 - bool queued_to_csi; 32 - }; 28 + static struct v4l2_subdev * 29 + sun6i_video_remote_subdev(struct sun6i_video *video, u32 *pad) 30 + { 31 + struct media_pad *remote; 33 32 34 - static const u32 supported_pixformats[] = { 33 + remote = media_pad_remote_pad_first(&video->pad); 34 + 35 + if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) 36 + return NULL; 37 + 38 + if (pad) 39 + *pad = remote->index; 40 + 41 + return media_entity_to_v4l2_subdev(remote->entity); 42 + } 43 + 44 + /* Format */ 45 + 46 + static const u32 sun6i_video_formats[] = { 35 47 V4L2_PIX_FMT_SBGGR8, 36 48 V4L2_PIX_FMT_SGBRG8, 37 49 V4L2_PIX_FMT_SGRBG8, ··· 73 61 V4L2_PIX_FMT_JPEG, 74 62 }; 75 63 76 - static bool is_pixformat_valid(unsigned int pixformat) 64 + static bool sun6i_video_format_check(u32 format) 77 65 { 78 66 unsigned int i; 79 67 80 - for (i = 0; i < ARRAY_SIZE(supported_pixformats); i++) 81 - if (supported_pixformats[i] == pixformat) 68 + for (i = 0; i < ARRAY_SIZE(sun6i_video_formats); i++) 69 + if (sun6i_video_formats[i] == format) 82 70 return true; 83 71 84 72 return false; 85 73 } 86 74 87 - static struct v4l2_subdev * 88 - sun6i_video_remote_subdev(struct sun6i_video *video, u32 *pad) 75 + /* Video */ 76 + 77 + static void sun6i_video_buffer_configure(struct sun6i_csi_device *csi_dev, 78 + struct sun6i_csi_buffer *csi_buffer) 89 79 { 90 - struct media_pad *remote; 91 - 92 - remote = media_pad_remote_pad_first(&video->pad); 93 - 94 - if (!remote || !is_media_entity_v4l2_subdev(remote->entity)) 95 - return NULL; 96 - 97 - if (pad) 98 - *pad = remote->index; 99 - 100 - return media_entity_to_v4l2_subdev(remote->entity); 80 + csi_buffer->queued_to_csi = true; 81 + sun6i_csi_update_buf_addr(csi_dev, csi_buffer->dma_addr); 101 82 } 102 83 103 - static int sun6i_video_queue_setup(struct vb2_queue *vq, 104 - unsigned int *nbuffers, 105 - unsigned int *nplanes, 84 + static void sun6i_video_configure(struct sun6i_csi_device *csi_dev) 85 + { 86 + struct sun6i_video *video = &csi_dev->video; 87 + struct sun6i_csi_config config = { 0 }; 88 + 89 + config.pixelformat = video->format.fmt.pix.pixelformat; 90 + config.code = video->mbus_code; 91 + config.field = video->format.fmt.pix.field; 92 + config.width = video->format.fmt.pix.width; 93 + config.height = video->format.fmt.pix.height; 94 + 95 + sun6i_csi_update_config(csi_dev, &config); 96 + } 97 + 98 + /* Queue */ 99 + 100 + static int sun6i_video_queue_setup(struct vb2_queue *queue, 101 + unsigned int *buffers_count, 102 + unsigned int *planes_count, 106 103 unsigned int sizes[], 107 104 struct device *alloc_devs[]) 108 105 { 109 - struct sun6i_video *video = vb2_get_drv_priv(vq); 110 - unsigned int size = video->fmt.fmt.pix.sizeimage; 106 + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); 107 + struct sun6i_video *video = &csi_dev->video; 108 + unsigned int size = video->format.fmt.pix.sizeimage; 111 109 112 - if (*nplanes) 110 + if (*planes_count) 113 111 return sizes[0] < size ? -EINVAL : 0; 114 112 115 - *nplanes = 1; 113 + *planes_count = 1; 116 114 sizes[0] = size; 117 115 118 116 return 0; 119 117 } 120 118 121 - static int sun6i_video_buffer_prepare(struct vb2_buffer *vb) 119 + static int sun6i_video_buffer_prepare(struct vb2_buffer *buffer) 122 120 { 123 - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 124 - struct sun6i_csi_buffer *buf = 125 - container_of(vbuf, struct sun6i_csi_buffer, vb); 126 - struct sun6i_video *video = vb2_get_drv_priv(vb->vb2_queue); 127 - unsigned long size = video->fmt.fmt.pix.sizeimage; 121 + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); 122 + struct sun6i_video *video = &csi_dev->video; 123 + struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; 124 + struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); 125 + struct sun6i_csi_buffer *csi_buffer = 126 + container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); 127 + unsigned long size = video->format.fmt.pix.sizeimage; 128 128 129 - if (vb2_plane_size(vb, 0) < size) { 130 - v4l2_err(video->vdev.v4l2_dev, "buffer too small (%lu < %lu)\n", 131 - vb2_plane_size(vb, 0), size); 129 + if (vb2_plane_size(buffer, 0) < size) { 130 + v4l2_err(v4l2_dev, "buffer too small (%lu < %lu)\n", 131 + vb2_plane_size(buffer, 0), size); 132 132 return -EINVAL; 133 133 } 134 134 135 - vb2_set_plane_payload(vb, 0, size); 135 + vb2_set_plane_payload(buffer, 0, size); 136 136 137 - buf->dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); 138 - 139 - vbuf->field = video->fmt.fmt.pix.field; 137 + csi_buffer->dma_addr = vb2_dma_contig_plane_dma_addr(buffer, 0); 138 + v4l2_buffer->field = video->format.fmt.pix.field; 140 139 141 140 return 0; 142 141 } 143 142 144 - static int sun6i_video_start_streaming(struct vb2_queue *vq, unsigned int count) 143 + static void sun6i_video_buffer_queue(struct vb2_buffer *buffer) 145 144 { 146 - struct sun6i_video *video = vb2_get_drv_priv(vq); 145 + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(buffer->vb2_queue); 146 + struct sun6i_video *video = &csi_dev->video; 147 + struct vb2_v4l2_buffer *v4l2_buffer = to_vb2_v4l2_buffer(buffer); 148 + struct sun6i_csi_buffer *csi_buffer = 149 + container_of(v4l2_buffer, struct sun6i_csi_buffer, v4l2_buffer); 150 + unsigned long flags; 151 + 152 + spin_lock_irqsave(&video->dma_queue_lock, flags); 153 + csi_buffer->queued_to_csi = false; 154 + list_add_tail(&csi_buffer->list, &video->dma_queue); 155 + spin_unlock_irqrestore(&video->dma_queue_lock, flags); 156 + } 157 + 158 + static int sun6i_video_start_streaming(struct vb2_queue *queue, 159 + unsigned int count) 160 + { 161 + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); 162 + struct sun6i_video *video = &csi_dev->video; 163 + struct video_device *video_dev = &video->video_dev; 147 164 struct sun6i_csi_buffer *buf; 148 165 struct sun6i_csi_buffer *next_buf; 149 - struct sun6i_csi_config config; 150 166 struct v4l2_subdev *subdev; 151 167 unsigned long flags; 152 168 int ret; 153 169 154 170 video->sequence = 0; 155 171 156 - ret = media_pipeline_start(&video->vdev.entity, &video->vdev.pipe); 172 + ret = video_device_pipeline_alloc_start(video_dev); 157 173 if (ret < 0) 158 - goto clear_dma_queue; 174 + goto error_dma_queue_flush; 159 175 160 176 if (video->mbus_code == 0) { 161 177 ret = -EINVAL; 162 - goto stop_media_pipeline; 178 + goto error_media_pipeline; 163 179 } 164 180 165 181 subdev = sun6i_video_remote_subdev(video, NULL); 166 182 if (!subdev) { 167 183 ret = -EINVAL; 168 - goto stop_media_pipeline; 184 + goto error_media_pipeline; 169 185 } 170 186 171 - config.pixelformat = video->fmt.fmt.pix.pixelformat; 172 - config.code = video->mbus_code; 173 - config.field = video->fmt.fmt.pix.field; 174 - config.width = video->fmt.fmt.pix.width; 175 - config.height = video->fmt.fmt.pix.height; 176 - 177 - ret = sun6i_csi_update_config(video->csi, &config); 178 - if (ret < 0) 179 - goto stop_media_pipeline; 187 + sun6i_video_configure(csi_dev); 180 188 181 189 spin_lock_irqsave(&video->dma_queue_lock, flags); 182 190 183 191 buf = list_first_entry(&video->dma_queue, 184 192 struct sun6i_csi_buffer, list); 185 - buf->queued_to_csi = true; 186 - sun6i_csi_update_buf_addr(video->csi, buf->dma_addr); 193 + sun6i_video_buffer_configure(csi_dev, buf); 187 194 188 - sun6i_csi_set_stream(video->csi, true); 195 + sun6i_csi_set_stream(csi_dev, true); 189 196 190 197 /* 191 198 * CSI will lookup the next dma buffer for next frame before the ··· 224 193 * would also drop frame when lacking of queued buffer. 225 194 */ 226 195 next_buf = list_next_entry(buf, list); 227 - next_buf->queued_to_csi = true; 228 - sun6i_csi_update_buf_addr(video->csi, next_buf->dma_addr); 196 + sun6i_video_buffer_configure(csi_dev, next_buf); 229 197 230 198 spin_unlock_irqrestore(&video->dma_queue_lock, flags); 231 199 232 200 ret = v4l2_subdev_call(subdev, video, s_stream, 1); 233 201 if (ret && ret != -ENOIOCTLCMD) 234 - goto stop_csi_stream; 202 + goto error_stream; 235 203 236 204 return 0; 237 205 238 - stop_csi_stream: 239 - sun6i_csi_set_stream(video->csi, false); 240 - stop_media_pipeline: 241 - media_pipeline_stop(&video->vdev.entity); 242 - clear_dma_queue: 206 + error_stream: 207 + sun6i_csi_set_stream(csi_dev, false); 208 + 209 + error_media_pipeline: 210 + video_device_pipeline_stop(video_dev); 211 + 212 + error_dma_queue_flush: 243 213 spin_lock_irqsave(&video->dma_queue_lock, flags); 244 214 list_for_each_entry(buf, &video->dma_queue, list) 245 - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); 215 + vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, 216 + VB2_BUF_STATE_QUEUED); 246 217 INIT_LIST_HEAD(&video->dma_queue); 247 218 spin_unlock_irqrestore(&video->dma_queue_lock, flags); 248 219 249 220 return ret; 250 221 } 251 222 252 - static void sun6i_video_stop_streaming(struct vb2_queue *vq) 223 + static void sun6i_video_stop_streaming(struct vb2_queue *queue) 253 224 { 254 - struct sun6i_video *video = vb2_get_drv_priv(vq); 225 + struct sun6i_csi_device *csi_dev = vb2_get_drv_priv(queue); 226 + struct sun6i_video *video = &csi_dev->video; 255 227 struct v4l2_subdev *subdev; 256 228 unsigned long flags; 257 229 struct sun6i_csi_buffer *buf; ··· 263 229 if (subdev) 264 230 v4l2_subdev_call(subdev, video, s_stream, 0); 265 231 266 - sun6i_csi_set_stream(video->csi, false); 232 + sun6i_csi_set_stream(csi_dev, false); 267 233 268 - media_pipeline_stop(&video->vdev.entity); 234 + video_device_pipeline_stop(&video->video_dev); 269 235 270 236 /* Release all active buffers */ 271 237 spin_lock_irqsave(&video->dma_queue_lock, flags); 272 238 list_for_each_entry(buf, &video->dma_queue, list) 273 - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 239 + vb2_buffer_done(&buf->v4l2_buffer.vb2_buf, VB2_BUF_STATE_ERROR); 274 240 INIT_LIST_HEAD(&video->dma_queue); 275 241 spin_unlock_irqrestore(&video->dma_queue_lock, flags); 276 242 } 277 243 278 - static void sun6i_video_buffer_queue(struct vb2_buffer *vb) 244 + void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev) 279 245 { 280 - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 281 - struct sun6i_csi_buffer *buf = 282 - container_of(vbuf, struct sun6i_csi_buffer, vb); 283 - struct sun6i_video *video = vb2_get_drv_priv(vb->vb2_queue); 284 - unsigned long flags; 285 - 286 - spin_lock_irqsave(&video->dma_queue_lock, flags); 287 - buf->queued_to_csi = false; 288 - list_add_tail(&buf->list, &video->dma_queue); 289 - spin_unlock_irqrestore(&video->dma_queue_lock, flags); 290 - } 291 - 292 - void sun6i_video_frame_done(struct sun6i_video *video) 293 - { 246 + struct sun6i_video *video = &csi_dev->video; 294 247 struct sun6i_csi_buffer *buf; 295 248 struct sun6i_csi_buffer *next_buf; 296 - struct vb2_v4l2_buffer *vbuf; 249 + struct vb2_v4l2_buffer *v4l2_buffer; 297 250 298 251 spin_lock(&video->dma_queue_lock); 299 252 300 253 buf = list_first_entry(&video->dma_queue, 301 254 struct sun6i_csi_buffer, list); 302 255 if (list_is_last(&buf->list, &video->dma_queue)) { 303 - dev_dbg(video->csi->dev, "Frame dropped!\n"); 304 - goto unlock; 256 + dev_dbg(csi_dev->dev, "Frame dropped!\n"); 257 + goto complete; 305 258 } 306 259 307 260 next_buf = list_next_entry(buf, list); ··· 298 277 * for next ISR call. 299 278 */ 300 279 if (!next_buf->queued_to_csi) { 301 - next_buf->queued_to_csi = true; 302 - sun6i_csi_update_buf_addr(video->csi, next_buf->dma_addr); 303 - dev_dbg(video->csi->dev, "Frame dropped!\n"); 304 - goto unlock; 280 + sun6i_video_buffer_configure(csi_dev, next_buf); 281 + dev_dbg(csi_dev->dev, "Frame dropped!\n"); 282 + goto complete; 305 283 } 306 284 307 285 list_del(&buf->list); 308 - vbuf = &buf->vb; 309 - vbuf->vb2_buf.timestamp = ktime_get_ns(); 310 - vbuf->sequence = video->sequence; 311 - vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); 286 + v4l2_buffer = &buf->v4l2_buffer; 287 + v4l2_buffer->vb2_buf.timestamp = ktime_get_ns(); 288 + v4l2_buffer->sequence = video->sequence; 289 + vb2_buffer_done(&v4l2_buffer->vb2_buf, VB2_BUF_STATE_DONE); 312 290 313 291 /* Prepare buffer for next frame but one. */ 314 292 if (!list_is_last(&next_buf->list, &video->dma_queue)) { 315 293 next_buf = list_next_entry(next_buf, list); 316 - next_buf->queued_to_csi = true; 317 - sun6i_csi_update_buf_addr(video->csi, next_buf->dma_addr); 294 + sun6i_video_buffer_configure(csi_dev, next_buf); 318 295 } else { 319 - dev_dbg(video->csi->dev, "Next frame will be dropped!\n"); 296 + dev_dbg(csi_dev->dev, "Next frame will be dropped!\n"); 320 297 } 321 298 322 - unlock: 299 + complete: 323 300 video->sequence++; 324 301 spin_unlock(&video->dma_queue_lock); 325 302 } 326 303 327 - static const struct vb2_ops sun6i_csi_vb2_ops = { 304 + static const struct vb2_ops sun6i_video_queue_ops = { 328 305 .queue_setup = sun6i_video_queue_setup, 329 - .wait_prepare = vb2_ops_wait_prepare, 330 - .wait_finish = vb2_ops_wait_finish, 331 306 .buf_prepare = sun6i_video_buffer_prepare, 307 + .buf_queue = sun6i_video_buffer_queue, 332 308 .start_streaming = sun6i_video_start_streaming, 333 309 .stop_streaming = sun6i_video_stop_streaming, 334 - .buf_queue = sun6i_video_buffer_queue, 310 + .wait_prepare = vb2_ops_wait_prepare, 311 + .wait_finish = vb2_ops_wait_finish, 335 312 }; 336 313 337 - static int vidioc_querycap(struct file *file, void *priv, 338 - struct v4l2_capability *cap) 339 - { 340 - struct sun6i_video *video = video_drvdata(file); 314 + /* V4L2 Device */ 341 315 342 - strscpy(cap->driver, "sun6i-video", sizeof(cap->driver)); 343 - strscpy(cap->card, video->vdev.name, sizeof(cap->card)); 344 - snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", 345 - video->csi->dev->of_node->name); 316 + static int sun6i_video_querycap(struct file *file, void *private, 317 + struct v4l2_capability *capability) 318 + { 319 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 320 + struct video_device *video_dev = &csi_dev->video.video_dev; 321 + 322 + strscpy(capability->driver, SUN6I_CSI_NAME, sizeof(capability->driver)); 323 + strscpy(capability->card, video_dev->name, sizeof(capability->card)); 324 + snprintf(capability->bus_info, sizeof(capability->bus_info), 325 + "platform:%s", dev_name(csi_dev->dev)); 346 326 347 327 return 0; 348 328 } 349 329 350 - static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, 351 - struct v4l2_fmtdesc *f) 330 + static int sun6i_video_enum_fmt(struct file *file, void *private, 331 + struct v4l2_fmtdesc *fmtdesc) 352 332 { 353 - u32 index = f->index; 333 + u32 index = fmtdesc->index; 354 334 355 - if (index >= ARRAY_SIZE(supported_pixformats)) 335 + if (index >= ARRAY_SIZE(sun6i_video_formats)) 356 336 return -EINVAL; 357 337 358 - f->pixelformat = supported_pixformats[index]; 338 + fmtdesc->pixelformat = sun6i_video_formats[index]; 359 339 360 340 return 0; 361 341 } 362 342 363 - static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 364 - struct v4l2_format *fmt) 343 + static int sun6i_video_g_fmt(struct file *file, void *private, 344 + struct v4l2_format *format) 365 345 { 366 - struct sun6i_video *video = video_drvdata(file); 346 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 347 + struct sun6i_video *video = &csi_dev->video; 367 348 368 - *fmt = video->fmt; 349 + *format = video->format; 369 350 370 351 return 0; 371 352 } 372 353 373 - static int sun6i_video_try_fmt(struct sun6i_video *video, 374 - struct v4l2_format *f) 354 + static int sun6i_video_format_try(struct sun6i_video *video, 355 + struct v4l2_format *format) 375 356 { 376 - struct v4l2_pix_format *pixfmt = &f->fmt.pix; 357 + struct v4l2_pix_format *pix_format = &format->fmt.pix; 377 358 int bpp; 378 359 379 - if (!is_pixformat_valid(pixfmt->pixelformat)) 380 - pixfmt->pixelformat = supported_pixformats[0]; 360 + if (!sun6i_video_format_check(pix_format->pixelformat)) 361 + pix_format->pixelformat = sun6i_video_formats[0]; 381 362 382 - v4l_bound_align_image(&pixfmt->width, MIN_WIDTH, MAX_WIDTH, 1, 383 - &pixfmt->height, MIN_HEIGHT, MAX_WIDTH, 1, 1); 363 + v4l_bound_align_image(&pix_format->width, MIN_WIDTH, MAX_WIDTH, 1, 364 + &pix_format->height, MIN_HEIGHT, MAX_WIDTH, 1, 1); 384 365 385 - bpp = sun6i_csi_get_bpp(pixfmt->pixelformat); 386 - pixfmt->bytesperline = (pixfmt->width * bpp) >> 3; 387 - pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 366 + bpp = sun6i_csi_get_bpp(pix_format->pixelformat); 367 + pix_format->bytesperline = (pix_format->width * bpp) >> 3; 368 + pix_format->sizeimage = pix_format->bytesperline * pix_format->height; 388 369 389 - if (pixfmt->field == V4L2_FIELD_ANY) 390 - pixfmt->field = V4L2_FIELD_NONE; 370 + if (pix_format->field == V4L2_FIELD_ANY) 371 + pix_format->field = V4L2_FIELD_NONE; 391 372 392 - if (pixfmt->pixelformat == V4L2_PIX_FMT_JPEG) 393 - pixfmt->colorspace = V4L2_COLORSPACE_JPEG; 373 + if (pix_format->pixelformat == V4L2_PIX_FMT_JPEG) 374 + pix_format->colorspace = V4L2_COLORSPACE_JPEG; 394 375 else 395 - pixfmt->colorspace = V4L2_COLORSPACE_SRGB; 376 + pix_format->colorspace = V4L2_COLORSPACE_SRGB; 396 377 397 - pixfmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 398 - pixfmt->quantization = V4L2_QUANTIZATION_DEFAULT; 399 - pixfmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; 378 + pix_format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 379 + pix_format->quantization = V4L2_QUANTIZATION_DEFAULT; 380 + pix_format->xfer_func = V4L2_XFER_FUNC_DEFAULT; 400 381 401 382 return 0; 402 383 } 403 384 404 - static int sun6i_video_set_fmt(struct sun6i_video *video, struct v4l2_format *f) 385 + static int sun6i_video_format_set(struct sun6i_video *video, 386 + struct v4l2_format *format) 405 387 { 406 388 int ret; 407 389 408 - ret = sun6i_video_try_fmt(video, f); 390 + ret = sun6i_video_format_try(video, format); 409 391 if (ret) 410 392 return ret; 411 393 412 - video->fmt = *f; 394 + video->format = *format; 413 395 414 396 return 0; 415 397 } 416 398 417 - static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 418 - struct v4l2_format *f) 399 + static int sun6i_video_s_fmt(struct file *file, void *private, 400 + struct v4l2_format *format) 419 401 { 420 - struct sun6i_video *video = video_drvdata(file); 402 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 403 + struct sun6i_video *video = &csi_dev->video; 421 404 422 - if (vb2_is_busy(&video->vb2_vidq)) 405 + if (vb2_is_busy(&video->queue)) 423 406 return -EBUSY; 424 407 425 - return sun6i_video_set_fmt(video, f); 408 + return sun6i_video_format_set(video, format); 426 409 } 427 410 428 - static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 429 - struct v4l2_format *f) 411 + static int sun6i_video_try_fmt(struct file *file, void *private, 412 + struct v4l2_format *format) 430 413 { 431 - struct sun6i_video *video = video_drvdata(file); 414 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 415 + struct sun6i_video *video = &csi_dev->video; 432 416 433 - return sun6i_video_try_fmt(video, f); 417 + return sun6i_video_format_try(video, format); 434 418 } 435 419 436 - static int vidioc_enum_input(struct file *file, void *fh, 437 - struct v4l2_input *inp) 420 + static int sun6i_video_enum_input(struct file *file, void *private, 421 + struct v4l2_input *input) 438 422 { 439 - if (inp->index != 0) 423 + if (input->index != 0) 440 424 return -EINVAL; 441 425 442 - strscpy(inp->name, "camera", sizeof(inp->name)); 443 - inp->type = V4L2_INPUT_TYPE_CAMERA; 426 + input->type = V4L2_INPUT_TYPE_CAMERA; 427 + strscpy(input->name, "Camera", sizeof(input->name)); 444 428 445 429 return 0; 446 430 } 447 431 448 - static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) 432 + static int sun6i_video_g_input(struct file *file, void *private, 433 + unsigned int *index) 449 434 { 450 - *i = 0; 435 + *index = 0; 451 436 452 437 return 0; 453 438 } 454 439 455 - static int vidioc_s_input(struct file *file, void *fh, unsigned int i) 440 + static int sun6i_video_s_input(struct file *file, void *private, 441 + unsigned int index) 456 442 { 457 - if (i != 0) 443 + if (index != 0) 458 444 return -EINVAL; 459 445 460 446 return 0; 461 447 } 462 448 463 449 static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { 464 - .vidioc_querycap = vidioc_querycap, 465 - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, 466 - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 467 - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 468 - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 450 + .vidioc_querycap = sun6i_video_querycap, 469 451 470 - .vidioc_enum_input = vidioc_enum_input, 471 - .vidioc_s_input = vidioc_s_input, 472 - .vidioc_g_input = vidioc_g_input, 452 + .vidioc_enum_fmt_vid_cap = sun6i_video_enum_fmt, 453 + .vidioc_g_fmt_vid_cap = sun6i_video_g_fmt, 454 + .vidioc_s_fmt_vid_cap = sun6i_video_s_fmt, 455 + .vidioc_try_fmt_vid_cap = sun6i_video_try_fmt, 473 456 474 - .vidioc_reqbufs = vb2_ioctl_reqbufs, 475 - .vidioc_querybuf = vb2_ioctl_querybuf, 476 - .vidioc_qbuf = vb2_ioctl_qbuf, 477 - .vidioc_expbuf = vb2_ioctl_expbuf, 478 - .vidioc_dqbuf = vb2_ioctl_dqbuf, 457 + .vidioc_enum_input = sun6i_video_enum_input, 458 + .vidioc_g_input = sun6i_video_g_input, 459 + .vidioc_s_input = sun6i_video_s_input, 460 + 479 461 .vidioc_create_bufs = vb2_ioctl_create_bufs, 480 462 .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 463 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 464 + .vidioc_querybuf = vb2_ioctl_querybuf, 465 + .vidioc_expbuf = vb2_ioctl_expbuf, 466 + .vidioc_qbuf = vb2_ioctl_qbuf, 467 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 481 468 .vidioc_streamon = vb2_ioctl_streamon, 482 469 .vidioc_streamoff = vb2_ioctl_streamoff, 483 - 484 - .vidioc_log_status = v4l2_ctrl_log_status, 485 - .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, 486 - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, 487 470 }; 488 471 489 - /* ----------------------------------------------------------------------------- 490 - * V4L2 file operations 491 - */ 472 + /* V4L2 File */ 473 + 492 474 static int sun6i_video_open(struct file *file) 493 475 { 494 - struct sun6i_video *video = video_drvdata(file); 476 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 477 + struct sun6i_video *video = &csi_dev->video; 495 478 int ret = 0; 496 479 497 480 if (mutex_lock_interruptible(&video->lock)) ··· 503 478 504 479 ret = v4l2_fh_open(file); 505 480 if (ret < 0) 506 - goto unlock; 481 + goto error_lock; 507 482 508 - ret = v4l2_pipeline_pm_get(&video->vdev.entity); 483 + ret = v4l2_pipeline_pm_get(&video->video_dev.entity); 509 484 if (ret < 0) 510 - goto fh_release; 485 + goto error_v4l2_fh; 511 486 512 - /* check if already powered */ 513 - if (!v4l2_fh_is_singular_file(file)) 514 - goto unlock; 515 - 516 - ret = sun6i_csi_set_power(video->csi, true); 517 - if (ret < 0) 518 - goto fh_release; 487 + /* Power on at first open. */ 488 + if (v4l2_fh_is_singular_file(file)) { 489 + ret = sun6i_csi_set_power(csi_dev, true); 490 + if (ret < 0) 491 + goto error_v4l2_fh; 492 + } 519 493 520 494 mutex_unlock(&video->lock); 495 + 521 496 return 0; 522 497 523 - fh_release: 498 + error_v4l2_fh: 524 499 v4l2_fh_release(file); 525 - unlock: 500 + 501 + error_lock: 526 502 mutex_unlock(&video->lock); 503 + 527 504 return ret; 528 505 } 529 506 530 507 static int sun6i_video_close(struct file *file) 531 508 { 532 - struct sun6i_video *video = video_drvdata(file); 533 - bool last_fh; 509 + struct sun6i_csi_device *csi_dev = video_drvdata(file); 510 + struct sun6i_video *video = &csi_dev->video; 511 + bool last_close; 534 512 535 513 mutex_lock(&video->lock); 536 514 537 - last_fh = v4l2_fh_is_singular_file(file); 515 + last_close = v4l2_fh_is_singular_file(file); 538 516 539 517 _vb2_fop_release(file, NULL); 518 + v4l2_pipeline_pm_put(&video->video_dev.entity); 540 519 541 - v4l2_pipeline_pm_put(&video->vdev.entity); 542 - 543 - if (last_fh) 544 - sun6i_csi_set_power(video->csi, false); 520 + /* Power off at last close. */ 521 + if (last_close) 522 + sun6i_csi_set_power(csi_dev, false); 545 523 546 524 mutex_unlock(&video->lock); 547 525 ··· 560 532 .poll = vb2_fop_poll 561 533 }; 562 534 563 - /* ----------------------------------------------------------------------------- 564 - * Media Operations 565 - */ 535 + /* Media Entity */ 536 + 566 537 static int sun6i_video_link_validate_get_format(struct media_pad *pad, 567 538 struct v4l2_subdev_format *fmt) 568 539 { ··· 581 554 { 582 555 struct video_device *vdev = container_of(link->sink->entity, 583 556 struct video_device, entity); 584 - struct sun6i_video *video = video_get_drvdata(vdev); 557 + struct sun6i_csi_device *csi_dev = video_get_drvdata(vdev); 558 + struct sun6i_video *video = &csi_dev->video; 585 559 struct v4l2_subdev_format source_fmt; 586 560 int ret; 587 561 588 562 video->mbus_code = 0; 589 563 590 564 if (!media_pad_remote_pad_first(link->sink->entity->pads)) { 591 - dev_info(video->csi->dev, 592 - "video node %s pad not connected\n", vdev->name); 565 + dev_info(csi_dev->dev, "video node %s pad not connected\n", 566 + vdev->name); 593 567 return -ENOLINK; 594 568 } 595 569 ··· 598 570 if (ret < 0) 599 571 return ret; 600 572 601 - if (!sun6i_csi_is_format_supported(video->csi, 602 - video->fmt.fmt.pix.pixelformat, 573 + if (!sun6i_csi_is_format_supported(csi_dev, 574 + video->format.fmt.pix.pixelformat, 603 575 source_fmt.format.code)) { 604 - dev_err(video->csi->dev, 576 + dev_err(csi_dev->dev, 605 577 "Unsupported pixformat: 0x%x with mbus code: 0x%x!\n", 606 - video->fmt.fmt.pix.pixelformat, 578 + video->format.fmt.pix.pixelformat, 607 579 source_fmt.format.code); 608 580 return -EPIPE; 609 581 } 610 582 611 - if (source_fmt.format.width != video->fmt.fmt.pix.width || 612 - source_fmt.format.height != video->fmt.fmt.pix.height) { 613 - dev_err(video->csi->dev, 583 + if (source_fmt.format.width != video->format.fmt.pix.width || 584 + source_fmt.format.height != video->format.fmt.pix.height) { 585 + dev_err(csi_dev->dev, 614 586 "Wrong width or height %ux%u (%ux%u expected)\n", 615 - video->fmt.fmt.pix.width, video->fmt.fmt.pix.height, 587 + video->format.fmt.pix.width, video->format.fmt.pix.height, 616 588 source_fmt.format.width, source_fmt.format.height); 617 589 return -EPIPE; 618 590 } ··· 626 598 .link_validate = sun6i_video_link_validate 627 599 }; 628 600 629 - int sun6i_video_init(struct sun6i_video *video, struct sun6i_csi *csi, 630 - const char *name) 601 + /* Video */ 602 + 603 + int sun6i_video_setup(struct sun6i_csi_device *csi_dev) 631 604 { 632 - struct video_device *vdev = &video->vdev; 633 - struct vb2_queue *vidq = &video->vb2_vidq; 634 - struct v4l2_format fmt = { 0 }; 605 + struct sun6i_video *video = &csi_dev->video; 606 + struct v4l2_device *v4l2_dev = &csi_dev->v4l2.v4l2_dev; 607 + struct video_device *video_dev = &video->video_dev; 608 + struct vb2_queue *queue = &video->queue; 609 + struct media_pad *pad = &video->pad; 610 + struct v4l2_format format = { 0 }; 611 + struct v4l2_pix_format *pix_format = &format.fmt.pix; 635 612 int ret; 636 613 637 - video->csi = csi; 614 + /* Media Entity */ 638 615 639 - /* Initialize the media entity... */ 640 - video->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; 641 - vdev->entity.ops = &sun6i_video_media_ops; 642 - ret = media_entity_pads_init(&vdev->entity, 1, &video->pad); 616 + video_dev->entity.ops = &sun6i_video_media_ops; 617 + 618 + /* Media Pad */ 619 + 620 + pad->flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; 621 + 622 + ret = media_entity_pads_init(&video_dev->entity, 1, pad); 643 623 if (ret < 0) 644 624 return ret; 645 625 646 - mutex_init(&video->lock); 626 + /* DMA queue */ 647 627 648 628 INIT_LIST_HEAD(&video->dma_queue); 649 629 spin_lock_init(&video->dma_queue_lock); 650 630 651 631 video->sequence = 0; 652 632 653 - /* Setup default format */ 654 - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 655 - fmt.fmt.pix.pixelformat = supported_pixformats[0]; 656 - fmt.fmt.pix.width = 1280; 657 - fmt.fmt.pix.height = 720; 658 - fmt.fmt.pix.field = V4L2_FIELD_NONE; 659 - sun6i_video_set_fmt(video, &fmt); 633 + /* Queue */ 660 634 661 - /* Initialize videobuf2 queue */ 662 - vidq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 663 - vidq->io_modes = VB2_MMAP | VB2_DMABUF; 664 - vidq->drv_priv = video; 665 - vidq->buf_struct_size = sizeof(struct sun6i_csi_buffer); 666 - vidq->ops = &sun6i_csi_vb2_ops; 667 - vidq->mem_ops = &vb2_dma_contig_memops; 668 - vidq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 669 - vidq->lock = &video->lock; 670 - /* Make sure non-dropped frame */ 671 - vidq->min_buffers_needed = 3; 672 - vidq->dev = csi->dev; 635 + mutex_init(&video->lock); 673 636 674 - ret = vb2_queue_init(vidq); 637 + queue->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 638 + queue->io_modes = VB2_MMAP | VB2_DMABUF; 639 + queue->buf_struct_size = sizeof(struct sun6i_csi_buffer); 640 + queue->ops = &sun6i_video_queue_ops; 641 + queue->mem_ops = &vb2_dma_contig_memops; 642 + queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 643 + queue->lock = &video->lock; 644 + queue->dev = csi_dev->dev; 645 + queue->drv_priv = csi_dev; 646 + 647 + /* Make sure non-dropped frame. */ 648 + queue->min_buffers_needed = 3; 649 + 650 + ret = vb2_queue_init(queue); 675 651 if (ret) { 676 - v4l2_err(&csi->v4l2_dev, "vb2_queue_init failed: %d\n", ret); 677 - goto clean_entity; 652 + v4l2_err(v4l2_dev, "failed to initialize vb2 queue: %d\n", ret); 653 + goto error_media_entity; 678 654 } 679 655 680 - /* Register video device */ 681 - strscpy(vdev->name, name, sizeof(vdev->name)); 682 - vdev->release = video_device_release_empty; 683 - vdev->fops = &sun6i_video_fops; 684 - vdev->ioctl_ops = &sun6i_video_ioctl_ops; 685 - vdev->vfl_type = VFL_TYPE_VIDEO; 686 - vdev->vfl_dir = VFL_DIR_RX; 687 - vdev->v4l2_dev = &csi->v4l2_dev; 688 - vdev->queue = vidq; 689 - vdev->lock = &video->lock; 690 - vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; 691 - video_set_drvdata(vdev, video); 656 + /* V4L2 Format */ 692 657 693 - ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); 658 + format.type = queue->type; 659 + pix_format->pixelformat = sun6i_video_formats[0]; 660 + pix_format->width = 1280; 661 + pix_format->height = 720; 662 + pix_format->field = V4L2_FIELD_NONE; 663 + 664 + sun6i_video_format_set(video, &format); 665 + 666 + /* Video Device */ 667 + 668 + strscpy(video_dev->name, SUN6I_CSI_NAME, sizeof(video_dev->name)); 669 + video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 670 + video_dev->vfl_dir = VFL_DIR_RX; 671 + video_dev->release = video_device_release_empty; 672 + video_dev->fops = &sun6i_video_fops; 673 + video_dev->ioctl_ops = &sun6i_video_ioctl_ops; 674 + video_dev->v4l2_dev = v4l2_dev; 675 + video_dev->queue = queue; 676 + video_dev->lock = &video->lock; 677 + 678 + video_set_drvdata(video_dev, csi_dev); 679 + 680 + ret = video_register_device(video_dev, VFL_TYPE_VIDEO, -1); 694 681 if (ret < 0) { 695 - v4l2_err(&csi->v4l2_dev, 696 - "video_register_device failed: %d\n", ret); 697 - goto clean_entity; 682 + v4l2_err(v4l2_dev, "failed to register video device: %d\n", 683 + ret); 684 + goto error_media_entity; 698 685 } 699 686 700 687 return 0; 701 688 702 - clean_entity: 703 - media_entity_cleanup(&video->vdev.entity); 689 + error_media_entity: 690 + media_entity_cleanup(&video_dev->entity); 691 + 704 692 mutex_destroy(&video->lock); 693 + 705 694 return ret; 706 695 } 707 696 708 - void sun6i_video_cleanup(struct sun6i_video *video) 697 + void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev) 709 698 { 710 - vb2_video_unregister_device(&video->vdev); 711 - media_entity_cleanup(&video->vdev.entity); 699 + struct sun6i_video *video = &csi_dev->video; 700 + struct video_device *video_dev = &video->video_dev; 701 + 702 + vb2_video_unregister_device(video_dev); 703 + media_entity_cleanup(&video_dev->entity); 712 704 mutex_destroy(&video->lock); 713 705 }
+10 -13
drivers/media/platform/sunxi/sun6i-csi/sun6i_video.h
··· 11 11 #include <media/v4l2-dev.h> 12 12 #include <media/videobuf2-core.h> 13 13 14 - struct sun6i_csi; 14 + struct sun6i_csi_device; 15 15 16 16 struct sun6i_video { 17 - struct video_device vdev; 17 + struct video_device video_dev; 18 + struct vb2_queue queue; 19 + struct mutex lock; /* Queue lock. */ 18 20 struct media_pad pad; 19 - struct sun6i_csi *csi; 20 21 21 - struct mutex lock; 22 - 23 - struct vb2_queue vb2_vidq; 24 - spinlock_t dma_queue_lock; 25 22 struct list_head dma_queue; 23 + spinlock_t dma_queue_lock; /* DMA queue lock. */ 26 24 27 - unsigned int sequence; 28 - struct v4l2_format fmt; 25 + struct v4l2_format format; 29 26 u32 mbus_code; 27 + unsigned int sequence; 30 28 }; 31 29 32 - int sun6i_video_init(struct sun6i_video *video, struct sun6i_csi *csi, 33 - const char *name); 34 - void sun6i_video_cleanup(struct sun6i_video *video); 30 + int sun6i_video_setup(struct sun6i_csi_device *csi_dev); 31 + void sun6i_video_cleanup(struct sun6i_csi_device *csi_dev); 35 32 36 - void sun6i_video_frame_done(struct sun6i_video *video); 33 + void sun6i_video_frame_done(struct sun6i_csi_device *csi_dev); 37 34 38 35 #endif /* __SUN6I_VIDEO_H__ */
+2 -2
drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
··· 3 3 tristate "Allwinner A31 MIPI CSI-2 Controller Driver" 4 4 depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV 5 5 depends on ARCH_SUNXI || COMPILE_TEST 6 - depends on PM && COMMON_CLK 6 + depends on PM && COMMON_CLK && RESET_CONTROLLER 7 + depends on PHY_SUN6I_MIPI_DPHY 7 8 select MEDIA_CONTROLLER 8 9 select VIDEO_V4L2_SUBDEV_API 9 10 select V4L2_FWNODE 10 - select PHY_SUN6I_MIPI_DPHY 11 11 select GENERIC_PHY_MIPI_DPHY 12 12 select REGMAP_MMIO 13 13 help
+16 -4
drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
··· 661 661 csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); 662 662 if (IS_ERR(csi2_dev->reset)) { 663 663 dev_err(dev, "failed to get reset controller\n"); 664 - return PTR_ERR(csi2_dev->reset); 664 + ret = PTR_ERR(csi2_dev->reset); 665 + goto error_clock_rate_exclusive; 665 666 } 666 667 667 668 /* D-PHY */ ··· 670 669 csi2_dev->dphy = devm_phy_get(dev, "dphy"); 671 670 if (IS_ERR(csi2_dev->dphy)) { 672 671 dev_err(dev, "failed to get MIPI D-PHY\n"); 673 - return PTR_ERR(csi2_dev->dphy); 672 + ret = PTR_ERR(csi2_dev->dphy); 673 + goto error_clock_rate_exclusive; 674 674 } 675 675 676 676 ret = phy_init(csi2_dev->dphy); 677 677 if (ret) { 678 678 dev_err(dev, "failed to initialize MIPI D-PHY\n"); 679 - return ret; 679 + goto error_clock_rate_exclusive; 680 680 } 681 681 682 682 /* Runtime PM */ ··· 685 683 pm_runtime_enable(dev); 686 684 687 685 return 0; 686 + 687 + error_clock_rate_exclusive: 688 + clk_rate_exclusive_put(csi2_dev->clock_mod); 689 + 690 + return ret; 688 691 } 689 692 690 693 static void ··· 719 712 720 713 ret = sun6i_mipi_csi2_bridge_setup(csi2_dev); 721 714 if (ret) 722 - return ret; 715 + goto error_resources; 723 716 724 717 return 0; 718 + 719 + error_resources: 720 + sun6i_mipi_csi2_resources_cleanup(csi2_dev); 721 + 722 + return ret; 725 723 } 726 724 727 725 static int sun6i_mipi_csi2_remove(struct platform_device *platform_dev)
+1 -1
drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
··· 3 3 tristate "Allwinner A83T MIPI CSI-2 Controller and D-PHY Driver" 4 4 depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV 5 5 depends on ARCH_SUNXI || COMPILE_TEST 6 - depends on PM && COMMON_CLK 6 + depends on PM && COMMON_CLK && RESET_CONTROLLER 7 7 select MEDIA_CONTROLLER 8 8 select VIDEO_V4L2_SUBDEV_API 9 9 select V4L2_FWNODE
+18 -5
drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
··· 719 719 csi2_dev->clock_mipi = devm_clk_get(dev, "mipi"); 720 720 if (IS_ERR(csi2_dev->clock_mipi)) { 721 721 dev_err(dev, "failed to acquire mipi clock\n"); 722 - return PTR_ERR(csi2_dev->clock_mipi); 722 + ret = PTR_ERR(csi2_dev->clock_mipi); 723 + goto error_clock_rate_exclusive; 723 724 } 724 725 725 726 csi2_dev->clock_misc = devm_clk_get(dev, "misc"); 726 727 if (IS_ERR(csi2_dev->clock_misc)) { 727 728 dev_err(dev, "failed to acquire misc clock\n"); 728 - return PTR_ERR(csi2_dev->clock_misc); 729 + ret = PTR_ERR(csi2_dev->clock_misc); 730 + goto error_clock_rate_exclusive; 729 731 } 730 732 731 733 /* Reset */ ··· 735 733 csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); 736 734 if (IS_ERR(csi2_dev->reset)) { 737 735 dev_err(dev, "failed to get reset controller\n"); 738 - return PTR_ERR(csi2_dev->reset); 736 + ret = PTR_ERR(csi2_dev->reset); 737 + goto error_clock_rate_exclusive; 739 738 } 740 739 741 740 /* D-PHY */ ··· 744 741 ret = sun8i_a83t_dphy_register(csi2_dev); 745 742 if (ret) { 746 743 dev_err(dev, "failed to initialize MIPI D-PHY\n"); 747 - return ret; 744 + goto error_clock_rate_exclusive; 748 745 } 749 746 750 747 /* Runtime PM */ ··· 752 749 pm_runtime_enable(dev); 753 750 754 751 return 0; 752 + 753 + error_clock_rate_exclusive: 754 + clk_rate_exclusive_put(csi2_dev->clock_mod); 755 + 756 + return ret; 755 757 } 756 758 757 759 static void ··· 786 778 787 779 ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev); 788 780 if (ret) 789 - return ret; 781 + goto error_resources; 790 782 791 783 return 0; 784 + 785 + error_resources: 786 + sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev); 787 + 788 + return ret; 792 789 } 793 790 794 791 static int sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev)
+1 -1
drivers/media/platform/sunxi/sun8i-di/Kconfig
··· 4 4 depends on V4L_MEM2MEM_DRIVERS 5 5 depends on VIDEO_DEV 6 6 depends on ARCH_SUNXI || COMPILE_TEST 7 - depends on COMMON_CLK && OF 7 + depends on COMMON_CLK && RESET_CONTROLLER && OF 8 8 depends on PM 9 9 select VIDEOBUF2_DMA_CONTIG 10 10 select V4L2_MEM2MEM_DEV
+1 -1
drivers/media/platform/sunxi/sun8i-rotate/Kconfig
··· 5 5 depends on V4L_MEM2MEM_DRIVERS 6 6 depends on VIDEO_DEV 7 7 depends on ARCH_SUNXI || COMPILE_TEST 8 - depends on COMMON_CLK && OF 8 + depends on COMMON_CLK && RESET_CONTROLLER && OF 9 9 depends on PM 10 10 select VIDEOBUF2_DMA_CONTIG 11 11 select V4L2_MEM2MEM_DEV
+3 -3
drivers/media/platform/ti/cal/cal-video.c
··· 708 708 dma_addr_t addr; 709 709 int ret; 710 710 711 - ret = media_pipeline_start(&ctx->vdev.entity, &ctx->phy->pipe); 711 + ret = video_device_pipeline_alloc_start(&ctx->vdev); 712 712 if (ret < 0) { 713 713 ctx_err(ctx, "Failed to start media pipeline: %d\n", ret); 714 714 goto error_release_buffers; ··· 761 761 cal_ctx_unprepare(ctx); 762 762 763 763 error_pipeline: 764 - media_pipeline_stop(&ctx->vdev.entity); 764 + video_device_pipeline_stop(&ctx->vdev); 765 765 error_release_buffers: 766 766 cal_release_buffers(ctx, VB2_BUF_STATE_QUEUED); 767 767 ··· 782 782 783 783 cal_release_buffers(ctx, VB2_BUF_STATE_ERROR); 784 784 785 - media_pipeline_stop(&ctx->vdev.entity); 785 + video_device_pipeline_stop(&ctx->vdev); 786 786 } 787 787 788 788 static const struct vb2_ops cal_video_qops = {
-1
drivers/media/platform/ti/cal/cal.h
··· 174 174 struct device_node *source_ep_node; 175 175 struct device_node *source_node; 176 176 struct v4l2_subdev *source; 177 - struct media_pipeline pipe; 178 177 179 178 struct v4l2_subdev subdev; 180 179 struct media_pad pads[CAL_CAMERARX_NUM_PADS];
+1 -3
drivers/media/platform/ti/omap3isp/isp.c
··· 937 937 struct isp_pipeline *pipe; 938 938 struct media_pad *pad; 939 939 940 - if (!me->pipe) 941 - return 0; 942 940 pipe = to_isp_pipeline(me); 943 - if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED) 941 + if (!pipe || pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED) 944 942 return 0; 945 943 pad = media_pad_remote_pad_first(&pipe->output->pad); 946 944 return pad->entity == me;
+4 -5
drivers/media/platform/ti/omap3isp/ispvideo.c
··· 1093 1093 /* Start streaming on the pipeline. No link touching an entity in the 1094 1094 * pipeline can be activated or deactivated once streaming is started. 1095 1095 */ 1096 - pipe = video->video.entity.pipe 1097 - ? to_isp_pipeline(&video->video.entity) : &video->pipe; 1096 + pipe = to_isp_pipeline(&video->video.entity) ? : &video->pipe; 1098 1097 1099 1098 ret = media_entity_enum_init(&pipe->ent_enum, &video->isp->media_dev); 1100 1099 if (ret) ··· 1103 1104 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); 1104 1105 pipe->max_rate = pipe->l3_ick; 1105 1106 1106 - ret = media_pipeline_start(&video->video.entity, &pipe->pipe); 1107 + ret = video_device_pipeline_start(&video->video, &pipe->pipe); 1107 1108 if (ret < 0) 1108 1109 goto err_pipeline_start; 1109 1110 ··· 1160 1161 return 0; 1161 1162 1162 1163 err_check_format: 1163 - media_pipeline_stop(&video->video.entity); 1164 + video_device_pipeline_stop(&video->video); 1164 1165 err_pipeline_start: 1165 1166 /* TODO: Implement PM QoS */ 1166 1167 /* The DMA queue must be emptied here, otherwise CCDC interrupts that ··· 1227 1228 video->error = false; 1228 1229 1229 1230 /* TODO: Implement PM QoS */ 1230 - media_pipeline_stop(&video->video.entity); 1231 + video_device_pipeline_stop(&video->video); 1231 1232 1232 1233 media_entity_enum_cleanup(&pipe->ent_enum); 1233 1234
+9 -2
drivers/media/platform/ti/omap3isp/ispvideo.h
··· 99 99 unsigned int external_width; 100 100 }; 101 101 102 - #define to_isp_pipeline(__e) \ 103 - container_of((__e)->pipe, struct isp_pipeline, pipe) 102 + static inline struct isp_pipeline *to_isp_pipeline(struct media_entity *entity) 103 + { 104 + struct media_pipeline *pipe = media_entity_pipeline(entity); 105 + 106 + if (!pipe) 107 + return NULL; 108 + 109 + return container_of(pipe, struct isp_pipeline, pipe); 110 + } 104 111 105 112 static inline int isp_pipeline_ready(struct isp_pipeline *pipe) 106 113 {
+9 -5
drivers/media/platform/verisilicon/hantro_drv.c
··· 251 251 252 252 static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) 253 253 { 254 + struct hantro_ctx *ctx; 255 + 256 + ctx = container_of(ctrl->handler, 257 + struct hantro_ctx, ctrl_handler); 258 + 254 259 if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) { 255 260 const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps; 256 261 ··· 271 266 } else if (ctrl->id == V4L2_CID_STATELESS_HEVC_SPS) { 272 267 const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; 273 268 274 - if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) 275 - /* Luma and chroma bit depth mismatch */ 269 + if (sps->bit_depth_luma_minus8 != 0 && sps->bit_depth_luma_minus8 != 2) 270 + /* Only 8-bit and 10-bit are supported */ 276 271 return -EINVAL; 277 - if (sps->bit_depth_luma_minus8 != 0) 278 - /* Only 8-bit is supported */ 279 - return -EINVAL; 272 + 273 + ctx->bit_depth = sps->bit_depth_luma_minus8 + 8; 280 274 } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) { 281 275 const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame; 282 276
+1 -3
drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
··· 12 12 13 13 static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx) 14 14 { 15 - return ctx->dst_fmt.width * ctx->dst_fmt.height; 15 + return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; 16 16 } 17 17 18 18 static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx) ··· 166 166 167 167 hantro_reg_write(vpu, &g2_bit_depth_y_minus8, sps->bit_depth_luma_minus8); 168 168 hantro_reg_write(vpu, &g2_bit_depth_c_minus8, sps->bit_depth_chroma_minus8); 169 - 170 - hantro_reg_write(vpu, &g2_output_8_bits, 0); 171 169 172 170 hantro_reg_write(vpu, &g2_hdr_skip_length, compute_header_skip_length(ctx)); 173 171
+2 -2
drivers/media/platform/verisilicon/hantro_hevc.c
··· 104 104 hevc_dec->tile_bsd.cpu = NULL; 105 105 } 106 106 107 - size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1); 107 + size = (VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8; 108 108 hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size, 109 109 &hevc_dec->tile_filter.dma, 110 110 GFP_KERNEL); ··· 112 112 goto err_free_tile_buffers; 113 113 hevc_dec->tile_filter.size = size; 114 114 115 - size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1); 115 + size = (VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8; 116 116 hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size, 117 117 &hevc_dec->tile_sao.dma, 118 118 GFP_KERNEL);
+6 -1
drivers/media/platform/verisilicon/hantro_postproc.c
··· 114 114 struct hantro_dev *vpu = ctx->dev; 115 115 struct vb2_v4l2_buffer *dst_buf; 116 116 int down_scale = down_scale_factor(ctx); 117 + int out_depth; 117 118 size_t chroma_offset; 118 119 dma_addr_t dst_dma; 119 120 ··· 133 132 hantro_write_addr(vpu, G2_RS_OUT_LUMA_ADDR, dst_dma); 134 133 hantro_write_addr(vpu, G2_RS_OUT_CHROMA_ADDR, dst_dma + chroma_offset); 135 134 } 135 + 136 + out_depth = hantro_get_format_depth(ctx->dst_fmt.pixelformat); 136 137 if (ctx->dev->variant->legacy_regs) { 137 - int out_depth = hantro_get_format_depth(ctx->dst_fmt.pixelformat); 138 138 u8 pp_shift = 0; 139 139 140 140 if (out_depth > 8) ··· 143 141 144 142 hantro_reg_write(ctx->dev, &g2_rs_out_bit_depth, out_depth); 145 143 hantro_reg_write(ctx->dev, &g2_pp_pix_shift, pp_shift); 144 + } else { 145 + hantro_reg_write(vpu, &g2_output_8_bits, out_depth > 8 ? 0 : 1); 146 + hantro_reg_write(vpu, &g2_output_format, out_depth > 8 ? 1 : 0); 146 147 } 147 148 hantro_reg_write(vpu, &g2_out_rs_e, 1); 148 149 }
+27
drivers/media/platform/verisilicon/imx8m_vpu_hw.c
··· 162 162 .step_height = MB_DIM, 163 163 }, 164 164 }, 165 + { 166 + .fourcc = V4L2_PIX_FMT_P010, 167 + .codec_mode = HANTRO_MODE_NONE, 168 + .postprocessed = true, 169 + .frmsize = { 170 + .min_width = FMT_MIN_WIDTH, 171 + .max_width = FMT_UHD_WIDTH, 172 + .step_width = MB_DIM, 173 + .min_height = FMT_MIN_HEIGHT, 174 + .max_height = FMT_UHD_HEIGHT, 175 + .step_height = MB_DIM, 176 + }, 177 + }, 165 178 }; 166 179 167 180 static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { 168 181 { 169 182 .fourcc = V4L2_PIX_FMT_NV12_4L4, 170 183 .codec_mode = HANTRO_MODE_NONE, 184 + .match_depth = true, 185 + .frmsize = { 186 + .min_width = FMT_MIN_WIDTH, 187 + .max_width = FMT_UHD_WIDTH, 188 + .step_width = TILE_MB_DIM, 189 + .min_height = FMT_MIN_HEIGHT, 190 + .max_height = FMT_UHD_HEIGHT, 191 + .step_height = TILE_MB_DIM, 192 + }, 193 + }, 194 + { 195 + .fourcc = V4L2_PIX_FMT_P010_4L4, 196 + .codec_mode = HANTRO_MODE_NONE, 197 + .match_depth = true, 171 198 .frmsize = { 172 199 .min_width = FMT_MIN_WIDTH, 173 200 .max_width = FMT_UHD_WIDTH,
+5 -6
drivers/media/platform/xilinx/xilinx-dma.c
··· 402 402 * Use the pipeline object embedded in the first DMA object that starts 403 403 * streaming. 404 404 */ 405 - pipe = dma->video.entity.pipe 406 - ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe; 405 + pipe = to_xvip_pipeline(&dma->video) ? : &dma->pipe; 407 406 408 - ret = media_pipeline_start(&dma->video.entity, &pipe->pipe); 407 + ret = video_device_pipeline_start(&dma->video, &pipe->pipe); 409 408 if (ret < 0) 410 409 goto error; 411 410 ··· 430 431 return 0; 431 432 432 433 error_stop: 433 - media_pipeline_stop(&dma->video.entity); 434 + video_device_pipeline_stop(&dma->video); 434 435 435 436 error: 436 437 /* Give back all queued buffers to videobuf2. */ ··· 447 448 static void xvip_dma_stop_streaming(struct vb2_queue *vq) 448 449 { 449 450 struct xvip_dma *dma = vb2_get_drv_priv(vq); 450 - struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video.entity); 451 + struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video); 451 452 struct xvip_dma_buffer *buf, *nbuf; 452 453 453 454 /* Stop the pipeline. */ ··· 458 459 459 460 /* Cleanup the pipeline and mark it as being stopped. */ 460 461 xvip_pipeline_cleanup(pipe); 461 - media_pipeline_stop(&dma->video.entity); 462 + video_device_pipeline_stop(&dma->video); 462 463 463 464 /* Give back all queued buffers to videobuf2. */ 464 465 spin_lock_irq(&dma->queued_lock);
+7 -2
drivers/media/platform/xilinx/xilinx-dma.h
··· 45 45 struct xvip_dma *output; 46 46 }; 47 47 48 - static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e) 48 + static inline struct xvip_pipeline *to_xvip_pipeline(struct video_device *vdev) 49 49 { 50 - return container_of(e->pipe, struct xvip_pipeline, pipe); 50 + struct media_pipeline *pipe = video_device_pipeline(vdev); 51 + 52 + if (!pipe) 53 + return NULL; 54 + 55 + return container_of(pipe, struct xvip_pipeline, pipe); 51 56 } 52 57 53 58 /**
+1 -4
drivers/media/radio/radio-si476x.c
··· 1072 1072 1073 1073 static int si476x_radio_fops_release(struct file *file) 1074 1074 { 1075 - int err; 1076 1075 struct si476x_radio *radio = video_drvdata(file); 1077 1076 1078 1077 if (v4l2_fh_is_singular_file(file) && ··· 1079 1080 si476x_core_set_power_state(radio->core, 1080 1081 SI476X_POWER_DOWN); 1081 1082 1082 - err = v4l2_fh_release(file); 1083 - 1084 - return err; 1083 + return v4l2_fh_release(file); 1085 1084 } 1086 1085 1087 1086 static ssize_t si476x_radio_fops_read(struct file *file, char __user *buf,
+1 -1
drivers/media/radio/si4713/si4713.c
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/i2c.h> 16 16 #include <linux/slab.h> 17 - #include <linux/gpio.h> 17 + #include <linux/gpio/consumer.h> 18 18 #include <linux/module.h> 19 19 #include <media/v4l2-device.h> 20 20 #include <media/v4l2-ioctl.h>
+1 -3
drivers/media/rc/imon.c
··· 684 684 */ 685 685 static int send_associate_24g(struct imon_context *ictx) 686 686 { 687 - int retval; 688 687 const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00, 689 688 0x00, 0x00, 0x00, 0x20 }; 690 689 ··· 698 699 } 699 700 700 701 memcpy(ictx->usb_tx_buf, packet, sizeof(packet)); 701 - retval = send_packet(ictx); 702 702 703 - return retval; 703 + return send_packet(ictx); 704 704 } 705 705 706 706 /*
+1 -1
drivers/media/rc/mceusb.c
··· 1077 1077 struct mceusb_dev *ir = dev->priv; 1078 1078 unsigned int units; 1079 1079 1080 - units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT); 1080 + units = DIV_ROUND_UP(timeout, MCE_TIME_UNIT); 1081 1081 1082 1082 cmdbuf[2] = units >> 8; 1083 1083 cmdbuf[3] = units;
+3 -4
drivers/media/test-drivers/vimc/vimc-capture.c
··· 241 241 static int vimc_capture_start_streaming(struct vb2_queue *vq, unsigned int count) 242 242 { 243 243 struct vimc_capture_device *vcapture = vb2_get_drv_priv(vq); 244 - struct media_entity *entity = &vcapture->vdev.entity; 245 244 int ret; 246 245 247 246 vcapture->sequence = 0; 248 247 249 248 /* Start the media pipeline */ 250 - ret = media_pipeline_start(entity, &vcapture->stream.pipe); 249 + ret = video_device_pipeline_start(&vcapture->vdev, &vcapture->stream.pipe); 251 250 if (ret) { 252 251 vimc_capture_return_all_buffers(vcapture, VB2_BUF_STATE_QUEUED); 253 252 return ret; ··· 254 255 255 256 ret = vimc_streamer_s_stream(&vcapture->stream, &vcapture->ved, 1); 256 257 if (ret) { 257 - media_pipeline_stop(entity); 258 + video_device_pipeline_stop(&vcapture->vdev); 258 259 vimc_capture_return_all_buffers(vcapture, VB2_BUF_STATE_QUEUED); 259 260 return ret; 260 261 } ··· 273 274 vimc_streamer_s_stream(&vcapture->stream, &vcapture->ved, 0); 274 275 275 276 /* Stop the media pipeline */ 276 - media_pipeline_stop(&vcapture->vdev.entity); 277 + video_device_pipeline_stop(&vcapture->vdev); 277 278 278 279 /* Release all active buffers */ 279 280 vimc_capture_return_all_buffers(vcapture, VB2_BUF_STATE_ERROR);
+1 -3
drivers/media/tuners/xc4000.c
··· 282 282 static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData) 283 283 { 284 284 u8 buf[4]; 285 - int result; 286 285 287 286 buf[0] = (regAddr >> 8) & 0xFF; 288 287 buf[1] = regAddr & 0xFF; 289 288 buf[2] = (i2cData >> 8) & 0xFF; 290 289 buf[3] = i2cData & 0xFF; 291 - result = xc_send_i2c_data(priv, buf, 4); 292 290 293 - return result; 291 + return xc_send_i2c_data(priv, buf, 4); 294 292 } 295 293 296 294 static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
+4 -4
drivers/media/usb/au0828/au0828-core.c
··· 410 410 goto end; 411 411 } 412 412 413 - ret = __media_pipeline_start(entity, pipe); 413 + ret = __media_pipeline_start(entity->pads, pipe); 414 414 if (ret) { 415 415 pr_err("Start Pipeline: %s->%s Error %d\n", 416 416 source->name, entity->name, ret); ··· 501 501 return; 502 502 503 503 /* stop pipeline */ 504 - __media_pipeline_stop(dev->active_link_owner); 504 + __media_pipeline_stop(dev->active_link_owner->pads); 505 505 pr_debug("Pipeline stop for %s\n", 506 506 dev->active_link_owner->name); 507 507 508 508 ret = __media_pipeline_start( 509 - dev->active_link_user, 509 + dev->active_link_user->pads, 510 510 dev->active_link_user_pipe); 511 511 if (ret) { 512 512 pr_err("Start Pipeline: %s->%s %d\n", ··· 532 532 return; 533 533 534 534 /* stop pipeline */ 535 - __media_pipeline_stop(dev->active_link_owner); 535 + __media_pipeline_stop(dev->active_link_owner->pads); 536 536 pr_debug("Pipeline stop for %s\n", 537 537 dev->active_link_owner->name); 538 538
+1 -1
drivers/media/usb/dvb-usb-v2/af9035.c
··· 1497 1497 /* 1498 1498 * AF9035 gpiot2 = FC0012 enable 1499 1499 * XXX: there seems to be something on gpioh8 too, but on my 1500 - * my test I didn't find any difference. 1500 + * test I didn't find any difference. 1501 1501 */ 1502 1502 1503 1503 if (adap->id == 0) {
+1 -1
drivers/media/usb/msi2500/msi2500.c
··· 209 209 * 210 210 * Control bits for previous samples is 32-bit field, containing 16 x 2-bit 211 211 * numbers. This results one 2-bit number for 8 samples. It is likely used for 212 - * for bit shifting sample by given bits, increasing actual sampling resolution. 212 + * bit shifting sample by given bits, increasing actual sampling resolution. 213 213 * Number 2 (0b10) was never seen. 214 214 * 215 215 * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes
+4 -4
drivers/media/v4l2-core/v4l2-ctrls-api.c
··· 89 89 /* Helper function: copy the initial control value back to the caller */ 90 90 static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl) 91 91 { 92 - ctrl->type_ops->init(ctrl, 0, ctrl->elems, ctrl->p_new); 92 + ctrl->type_ops->init(ctrl, 0, ctrl->p_new); 93 93 94 94 return ptr_to_user(c, ctrl, ctrl->p_new); 95 95 } ··· 126 126 if (ctrl->is_dyn_array) 127 127 ctrl->new_elems = elems; 128 128 else if (ctrl->is_array) 129 - ctrl->type_ops->init(ctrl, elems, ctrl->elems, ctrl->p_new); 129 + ctrl->type_ops->init(ctrl, elems, ctrl->p_new); 130 130 return 0; 131 131 } 132 132 ··· 494 494 /* Validate a new control */ 495 495 static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new) 496 496 { 497 - return ctrl->type_ops->validate(ctrl, ctrl->new_elems, p_new); 497 + return ctrl->type_ops->validate(ctrl, p_new); 498 498 } 499 499 500 500 /* Validate controls. */ ··· 1007 1007 ctrl->p_cur.p = p_array + elems * ctrl->elem_size; 1008 1008 for (i = 0; i < ctrl->nr_of_dims; i++) 1009 1009 ctrl->dims[i] = dims[i]; 1010 - ctrl->type_ops->init(ctrl, 0, elems, ctrl->p_cur); 1010 + ctrl->type_ops->init(ctrl, 0, ctrl->p_cur); 1011 1011 cur_to_new(ctrl); 1012 1012 send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_VALUE | 1013 1013 V4L2_EVENT_CTRL_CH_DIMENSIONS);
+10 -9
drivers/media/v4l2-core/v4l2-ctrls-core.c
··· 65 65 v4l2_event_queue_fh(sev->fh, &ev); 66 66 } 67 67 68 - bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, u32 elems, 68 + bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, 69 69 union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2) 70 70 { 71 71 unsigned int i; ··· 74 74 case V4L2_CTRL_TYPE_BUTTON: 75 75 return false; 76 76 case V4L2_CTRL_TYPE_STRING: 77 - for (i = 0; i < elems; i++) { 77 + for (i = 0; i < ctrl->elems; i++) { 78 78 unsigned int idx = i * ctrl->elem_size; 79 79 80 80 /* strings are always 0-terminated */ ··· 84 84 return true; 85 85 default: 86 86 return !memcmp(ptr1.p_const, ptr2.p_const, 87 - elems * ctrl->elem_size); 87 + ctrl->elems * ctrl->elem_size); 88 88 } 89 89 } 90 90 EXPORT_SYMBOL(v4l2_ctrl_type_op_equal); ··· 178 178 } 179 179 180 180 void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, 181 - u32 tot_elems, union v4l2_ctrl_ptr ptr) 181 + union v4l2_ctrl_ptr ptr) 182 182 { 183 183 unsigned int i; 184 + u32 tot_elems = ctrl->elems; 184 185 u32 elems = tot_elems - from_idx; 185 186 186 187 if (from_idx >= tot_elems) ··· 996 995 } 997 996 } 998 997 999 - int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, u32 elems, 998 + int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, 1000 999 union v4l2_ctrl_ptr ptr) 1001 1000 { 1002 1001 unsigned int i; ··· 1018 1017 1019 1018 case V4L2_CTRL_TYPE_BUTTON: 1020 1019 case V4L2_CTRL_TYPE_CTRL_CLASS: 1021 - memset(ptr.p_s32, 0, elems * sizeof(s32)); 1020 + memset(ptr.p_s32, 0, ctrl->new_elems * sizeof(s32)); 1022 1021 return 0; 1023 1022 } 1024 1023 1025 - for (i = 0; !ret && i < elems; i++) 1024 + for (i = 0; !ret && i < ctrl->new_elems; i++) 1026 1025 ret = std_validate_elem(ctrl, i, ptr); 1027 1026 return ret; 1028 1027 } ··· 1725 1724 memcpy(ctrl->p_def.p, p_def.p_const, elem_size); 1726 1725 } 1727 1726 1728 - ctrl->type_ops->init(ctrl, 0, elems, ctrl->p_cur); 1727 + ctrl->type_ops->init(ctrl, 0, ctrl->p_cur); 1729 1728 cur_to_new(ctrl); 1730 1729 1731 1730 if (handler_new_ref(hdl, ctrl, NULL, false, false)) { ··· 2070 2069 ctrl_changed = true; 2071 2070 if (!ctrl_changed) 2072 2071 ctrl_changed = !ctrl->type_ops->equal(ctrl, 2073 - ctrl->elems, ctrl->p_cur, ctrl->p_new); 2072 + ctrl->p_cur, ctrl->p_new); 2074 2073 ctrl->has_changed = ctrl_changed; 2075 2074 changed |= ctrl->has_changed; 2076 2075 }
+72
drivers/media/v4l2-core/v4l2-dev.c
··· 1095 1095 } 1096 1096 EXPORT_SYMBOL(video_unregister_device); 1097 1097 1098 + #if defined(CONFIG_MEDIA_CONTROLLER) 1099 + 1100 + __must_check int video_device_pipeline_start(struct video_device *vdev, 1101 + struct media_pipeline *pipe) 1102 + { 1103 + struct media_entity *entity = &vdev->entity; 1104 + 1105 + if (entity->num_pads != 1) 1106 + return -ENODEV; 1107 + 1108 + return media_pipeline_start(&entity->pads[0], pipe); 1109 + } 1110 + EXPORT_SYMBOL_GPL(video_device_pipeline_start); 1111 + 1112 + __must_check int __video_device_pipeline_start(struct video_device *vdev, 1113 + struct media_pipeline *pipe) 1114 + { 1115 + struct media_entity *entity = &vdev->entity; 1116 + 1117 + if (entity->num_pads != 1) 1118 + return -ENODEV; 1119 + 1120 + return __media_pipeline_start(&entity->pads[0], pipe); 1121 + } 1122 + EXPORT_SYMBOL_GPL(__video_device_pipeline_start); 1123 + 1124 + void video_device_pipeline_stop(struct video_device *vdev) 1125 + { 1126 + struct media_entity *entity = &vdev->entity; 1127 + 1128 + if (WARN_ON(entity->num_pads != 1)) 1129 + return; 1130 + 1131 + return media_pipeline_stop(&entity->pads[0]); 1132 + } 1133 + EXPORT_SYMBOL_GPL(video_device_pipeline_stop); 1134 + 1135 + void __video_device_pipeline_stop(struct video_device *vdev) 1136 + { 1137 + struct media_entity *entity = &vdev->entity; 1138 + 1139 + if (WARN_ON(entity->num_pads != 1)) 1140 + return; 1141 + 1142 + return __media_pipeline_stop(&entity->pads[0]); 1143 + } 1144 + EXPORT_SYMBOL_GPL(__video_device_pipeline_stop); 1145 + 1146 + __must_check int video_device_pipeline_alloc_start(struct video_device *vdev) 1147 + { 1148 + struct media_entity *entity = &vdev->entity; 1149 + 1150 + if (entity->num_pads != 1) 1151 + return -ENODEV; 1152 + 1153 + return media_pipeline_alloc_start(&entity->pads[0]); 1154 + } 1155 + EXPORT_SYMBOL_GPL(video_device_pipeline_alloc_start); 1156 + 1157 + struct media_pipeline *video_device_pipeline(struct video_device *vdev) 1158 + { 1159 + struct media_entity *entity = &vdev->entity; 1160 + 1161 + if (WARN_ON(entity->num_pads != 1)) 1162 + return NULL; 1163 + 1164 + return media_pad_pipeline(&entity->pads[0]); 1165 + } 1166 + EXPORT_SYMBOL_GPL(video_device_pipeline); 1167 + 1168 + #endif /* CONFIG_MEDIA_CONTROLLER */ 1169 + 1098 1170 /* 1099 1171 * Initialise video for linux 1100 1172 */
-1
drivers/staging/media/atomisp/Makefile
··· 17 17 pci/atomisp_compat_css20.o \ 18 18 pci/atomisp_csi2.o \ 19 19 pci/atomisp_drvfs.o \ 20 - pci/atomisp_file.o \ 21 20 pci/atomisp_fops.o \ 22 21 pci/atomisp_ioctl.o \ 23 22 pci/atomisp_subdev.o \
+9 -10
drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
··· 841 841 if (!ov2680_info) 842 842 return -EINVAL; 843 843 844 - mutex_lock(&dev->input_lock); 845 - 846 844 res = v4l2_find_nearest_size(ov2680_res_preview, 847 845 ARRAY_SIZE(ov2680_res_preview), width, 848 846 height, fmt->width, fmt->height); ··· 853 855 fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; 854 856 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 855 857 sd_state->pads->try_fmt = *fmt; 856 - mutex_unlock(&dev->input_lock); 857 858 return 0; 858 859 } 859 860 860 861 dev_dbg(&client->dev, "%s: %dx%d\n", 861 862 __func__, fmt->width, fmt->height); 862 863 864 + mutex_lock(&dev->input_lock); 865 + 863 866 /* s_power has not been called yet for std v4l2 clients (camorama) */ 864 867 power_up(sd); 865 868 ret = ov2680_write_reg_array(client, dev->res->regs); 866 - if (ret) 869 + if (ret) { 867 870 dev_err(&client->dev, 868 871 "ov2680 write resolution register err: %d\n", ret); 872 + goto err; 873 + } 869 874 870 875 vts = dev->res->lines_per_frame; 871 876 ··· 877 876 vts = dev->exposure + OV2680_INTEGRATION_TIME_MARGIN; 878 877 879 878 ret = ov2680_write_reg(client, 2, OV2680_TIMING_VTS_H, vts); 880 - if (ret) 879 + if (ret) { 881 880 dev_err(&client->dev, "ov2680 write vts err: %d\n", ret); 881 + goto err; 882 + } 882 883 883 884 ret = ov2680_get_intg_factor(client, ov2680_info, res); 884 885 if (ret) { ··· 897 894 if (v_flag) 898 895 ov2680_v_flip(sd, v_flag); 899 896 900 - /* 901 - * ret = startup(sd); 902 - * if (ret) 903 - * dev_err(&client->dev, "ov2680 startup err\n"); 904 - */ 897 + dev->res = res; 905 898 err: 906 899 mutex_unlock(&dev->input_lock); 907 900 return ret;
-6
drivers/staging/media/atomisp/include/hmm/hmm_bo.h
··· 65 65 #define check_bo_null_return_void(bo) \ 66 66 check_null_return_void(bo, "NULL hmm buffer object.\n") 67 67 68 - #define HMM_MAX_ORDER 3 69 - #define HMM_MIN_ORDER 0 70 - 71 68 #define ISP_VM_START 0x0 72 69 #define ISP_VM_SIZE (0x7FFFFFFF) /* 2G address space */ 73 70 #define ISP_PTR_NULL NULL ··· 86 89 #define HMM_BO_VMAPED 0x10 87 90 #define HMM_BO_VMAPED_CACHED 0x20 88 91 #define HMM_BO_ACTIVE 0x1000 89 - #define HMM_BO_MEM_TYPE_USER 0x1 90 - #define HMM_BO_MEM_TYPE_PFN 0x2 91 92 92 93 struct hmm_bo_device { 93 94 struct isp_mmu mmu; ··· 121 126 enum hmm_bo_type type; 122 127 int mmap_count; 123 128 int status; 124 - int mem_type; 125 129 void *vmap_addr; /* kernel virtual address by vmap */ 126 130 127 131 struct rb_node node;
-14
drivers/staging/media/atomisp/include/linux/atomisp.h
··· 740 740 ATOMISP_FRAME_STATUS_FLASH_FAILED, 741 741 }; 742 742 743 - /* ISP memories, isp2400 */ 744 - enum atomisp_acc_memory { 745 - ATOMISP_ACC_MEMORY_PMEM0 = 0, 746 - ATOMISP_ACC_MEMORY_DMEM0, 747 - /* for backward compatibility */ 748 - ATOMISP_ACC_MEMORY_DMEM = ATOMISP_ACC_MEMORY_DMEM0, 749 - ATOMISP_ACC_MEMORY_VMEM0, 750 - ATOMISP_ACC_MEMORY_VAMEM0, 751 - ATOMISP_ACC_MEMORY_VAMEM1, 752 - ATOMISP_ACC_MEMORY_VAMEM2, 753 - ATOMISP_ACC_MEMORY_HMEM0, 754 - ATOMISP_ACC_NR_MEMORY 755 - }; 756 - 757 743 enum atomisp_ext_isp_id { 758 744 EXT_ISP_CID_ISO = 0, 759 745 EXT_ISP_CID_CAPTURE_HDR,
-2
drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
··· 26 26 int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd); 27 27 int gmin_get_var_int(struct device *dev, bool is_gmin, 28 28 const char *var, int def); 29 - int camera_sensor_csi(struct v4l2_subdev *sd, u32 port, 30 - u32 lanes, u32 format, u32 bayer_order, int flag); 31 29 struct camera_sensor_platform_data * 32 30 gmin_camera_platform_data( 33 31 struct v4l2_subdev *subdev,
-18
drivers/staging/media/atomisp/include/linux/atomisp_platform.h
··· 141 141 struct intel_v4l2_subdev_table *subdevs; 142 142 }; 143 143 144 - /* Describe the capacities of one single sensor. */ 145 - struct atomisp_sensor_caps { 146 - /* The number of streams this sensor can output. */ 147 - int stream_num; 148 - bool is_slave; 149 - }; 150 - 151 - /* Describe the capacities of sensors connected to one camera port. */ 152 - struct atomisp_camera_caps { 153 - /* The number of sensors connected to this camera port. */ 154 - int sensor_num; 155 - /* The capacities of each sensor. */ 156 - struct atomisp_sensor_caps sensor[MAX_SENSORS_PER_PORT]; 157 - /* Define whether stream control is required for multiple streams. */ 158 - bool multi_stream_ctrl; 159 - }; 160 - 161 144 /* 162 145 * Sensor of external ISP can send multiple steams with different mipi data 163 146 * type in the same virtual channel. This information needs to come from the ··· 218 235 }; 219 236 220 237 const struct atomisp_platform_data *atomisp_get_platform_data(void); 221 - const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void); 222 238 223 239 /* API from old platform_camera.h, new CPUID implementation */ 224 240 #define __IS_SOC(x) (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && \
+19
drivers/staging/media/atomisp/notes.txt
··· 28 28 this means that unlike in fixed pipelines the soft pipelines 29 29 on the ISP can do multiple processing steps in a single pipeline 30 30 element (in a single binary). 31 + 32 + ### 33 + 34 + The sensor drivers use of v4l2_get_subdev_hostdata(), which returns 35 + a camera_mipi_info struct. This struct is allocated/managed by 36 + the core atomisp code. The most important parts of the struct 37 + are filled by the atomisp core itself, like e.g. the port number. 38 + 39 + The sensor drivers on a set_fmt call do fill in camera_mipi_info.data 40 + which is a atomisp_sensor_mode_data struct. This gets filled from 41 + a function called <sensor_name>_get_intg_factor(). This struct is not 42 + used by the atomisp code at all. It is returned to userspace by 43 + a ATOMISP_IOC_G_SENSOR_MODE_DATA and the Android userspace does use this. 44 + 45 + Other members of camera_mipi_info which are set by some drivers are: 46 + -metadata_width, metadata_height, metadata_effective_width, set by 47 + the ov5693 driver (and used by the atomisp core) 48 + -raw_bayer_order, adjusted by the ov2680 driver when flipping since 49 + flipping can change the bayer order
+67 -648
drivers/staging/media/atomisp/pci/atomisp_cmd.c
··· 80 80 } ptr; 81 81 }; 82 82 83 + static int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id); 84 + 83 85 /* 84 86 * get sensor:dis71430/ov2720 related info from v4l2_subdev->priv data field. 85 87 * subdev->priv is set in mrst.c ··· 98 96 { 99 97 return (struct atomisp_video_pipe *) 100 98 container_of(dev, struct atomisp_video_pipe, vdev); 101 - } 102 - 103 - /* 104 - * get struct atomisp_acc_pipe from v4l2 video_device 105 - */ 106 - struct atomisp_acc_pipe *atomisp_to_acc_pipe(struct video_device *dev) 107 - { 108 - return (struct atomisp_acc_pipe *) 109 - container_of(dev, struct atomisp_acc_pipe, vdev); 110 99 } 111 100 112 101 static unsigned short atomisp_get_sensor_fps(struct atomisp_sub_device *asd) ··· 770 777 enum ia_css_pipe_id css_pipe_id, 771 778 enum ia_css_buffer_type buf_type) 772 779 { 773 - struct atomisp_device *isp = asd->isp; 774 - 775 - if (css_pipe_id == IA_CSS_PIPE_ID_COPY && 776 - isp->inputs[asd->input_curr].camera_caps-> 777 - sensor[asd->sensor_curr].stream_num > 1) { 778 - switch (stream_id) { 779 - case ATOMISP_INPUT_STREAM_PREVIEW: 780 - return &asd->video_out_preview; 781 - case ATOMISP_INPUT_STREAM_POSTVIEW: 782 - return &asd->video_out_vf; 783 - case ATOMISP_INPUT_STREAM_VIDEO: 784 - return &asd->video_out_video_capture; 785 - case ATOMISP_INPUT_STREAM_CAPTURE: 786 - default: 787 - return &asd->video_out_capture; 788 - } 789 - } 790 - 791 780 /* video is same in online as in continuouscapture mode */ 792 781 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) { 793 782 /* ··· 881 906 enum atomisp_metadata_type md_type; 882 907 struct atomisp_device *isp = asd->isp; 883 908 struct v4l2_control ctrl; 884 - bool reset_wdt_timer = false; 909 + 910 + lockdep_assert_held(&isp->mutex); 885 911 886 912 if ( 887 913 buf_type != IA_CSS_BUFFER_TYPE_METADATA && ··· 989 1013 break; 990 1014 case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME: 991 1015 case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME: 992 - if (IS_ISP2401) 993 - reset_wdt_timer = true; 994 - 995 1016 pipe->buffers_in_css--; 996 1017 frame = buffer.css_buffer.data.frame; 997 1018 if (!frame) { ··· 1041 1068 break; 1042 1069 case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME: 1043 1070 case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME: 1044 - if (IS_ISP2401) 1045 - reset_wdt_timer = true; 1046 - 1047 1071 pipe->buffers_in_css--; 1048 1072 frame = buffer.css_buffer.data.frame; 1049 1073 if (!frame) { ··· 1208 1238 */ 1209 1239 wake_up(&vb->done); 1210 1240 } 1211 - if (IS_ISP2401) 1212 - atomic_set(&pipe->wdt_count, 0); 1213 1241 1214 1242 /* 1215 1243 * Requeue should only be done for 3a and dis buffers. ··· 1224 1256 } 1225 1257 if (!error && q_buffers) 1226 1258 atomisp_qbuffers_to_css(asd); 1227 - 1228 - if (IS_ISP2401) { 1229 - /* If there are no buffers queued then 1230 - * delete wdt timer. */ 1231 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 1232 - return; 1233 - if (!atomisp_buffers_queued_pipe(pipe)) 1234 - atomisp_wdt_stop_pipe(pipe, false); 1235 - else if (reset_wdt_timer) 1236 - /* SOF irq should not reset wdt timer. */ 1237 - atomisp_wdt_refresh_pipe(pipe, 1238 - ATOMISP_WDT_KEEP_CURRENT_DELAY); 1239 - } 1240 1259 } 1241 1260 1242 1261 void atomisp_delayed_init_work(struct work_struct *work) ··· 1262 1307 bool stream_restart[MAX_STREAM_NUM] = {0}; 1263 1308 bool depth_mode = false; 1264 1309 int i, ret, depth_cnt = 0; 1310 + unsigned long flags; 1265 1311 1266 - if (!isp->sw_contex.file_input) 1267 - atomisp_css_irq_enable(isp, 1268 - IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); 1312 + lockdep_assert_held(&isp->mutex); 1313 + 1314 + if (!atomisp_streaming_count(isp)) 1315 + return; 1316 + 1317 + atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); 1269 1318 1270 1319 BUG_ON(isp->num_of_streams > MAX_STREAM_NUM); 1271 1320 ··· 1290 1331 1291 1332 stream_restart[asd->index] = true; 1292 1333 1334 + spin_lock_irqsave(&isp->lock, flags); 1293 1335 asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING; 1336 + spin_unlock_irqrestore(&isp->lock, flags); 1294 1337 1295 1338 /* stream off sensor */ 1296 1339 ret = v4l2_subdev_call( ··· 1307 1346 css_pipe_id = atomisp_get_css_pipe_id(asd); 1308 1347 atomisp_css_stop(asd, css_pipe_id, true); 1309 1348 1349 + spin_lock_irqsave(&isp->lock, flags); 1310 1350 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 1351 + spin_unlock_irqrestore(&isp->lock, flags); 1311 1352 1312 1353 asd->preview_exp_id = 1; 1313 1354 asd->postview_exp_id = 1; ··· 1350 1387 IA_CSS_INPUT_MODE_BUFFERED_SENSOR); 1351 1388 1352 1389 css_pipe_id = atomisp_get_css_pipe_id(asd); 1353 - if (atomisp_css_start(asd, css_pipe_id, true)) 1390 + if (atomisp_css_start(asd, css_pipe_id, true)) { 1354 1391 dev_warn(isp->dev, 1355 1392 "start SP failed, so do not set streaming to be enable!\n"); 1356 - else 1393 + } else { 1394 + spin_lock_irqsave(&isp->lock, flags); 1357 1395 asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED; 1396 + spin_unlock_irqrestore(&isp->lock, flags); 1397 + } 1358 1398 1359 1399 atomisp_csi2_configure(asd); 1360 1400 } 1361 1401 1362 - if (!isp->sw_contex.file_input) { 1363 - atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1364 - atomisp_css_valid_sof(isp)); 1402 + atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1403 + atomisp_css_valid_sof(isp)); 1365 1404 1366 - if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, true) < 0) 1367 - dev_dbg(isp->dev, "DFS auto failed while recovering!\n"); 1368 - } else { 1369 - if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, true) < 0) 1370 - dev_dbg(isp->dev, "DFS max failed while recovering!\n"); 1371 - } 1405 + if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, true) < 0) 1406 + dev_dbg(isp->dev, "DFS auto failed while recovering!\n"); 1372 1407 1373 1408 for (i = 0; i < isp->num_of_streams; i++) { 1374 1409 struct atomisp_sub_device *asd; ··· 1415 1454 } 1416 1455 } 1417 1456 1418 - void atomisp_wdt_work(struct work_struct *work) 1457 + void atomisp_assert_recovery_work(struct work_struct *work) 1419 1458 { 1420 1459 struct atomisp_device *isp = container_of(work, struct atomisp_device, 1421 - wdt_work); 1422 - int i; 1423 - unsigned int pipe_wdt_cnt[MAX_STREAM_NUM][4] = { {0} }; 1424 - bool css_recover = true; 1460 + assert_recovery_work); 1425 1461 1426 - rt_mutex_lock(&isp->mutex); 1427 - if (!atomisp_streaming_count(isp)) { 1428 - atomic_set(&isp->wdt_work_queued, 0); 1429 - rt_mutex_unlock(&isp->mutex); 1430 - return; 1431 - } 1432 - 1433 - if (!IS_ISP2401) { 1434 - dev_err(isp->dev, "timeout %d of %d\n", 1435 - atomic_read(&isp->wdt_count) + 1, 1436 - ATOMISP_ISP_MAX_TIMEOUT_COUNT); 1437 - } else { 1438 - for (i = 0; i < isp->num_of_streams; i++) { 1439 - struct atomisp_sub_device *asd = &isp->asd[i]; 1440 - 1441 - pipe_wdt_cnt[i][0] += 1442 - atomic_read(&asd->video_out_capture.wdt_count); 1443 - pipe_wdt_cnt[i][1] += 1444 - atomic_read(&asd->video_out_vf.wdt_count); 1445 - pipe_wdt_cnt[i][2] += 1446 - atomic_read(&asd->video_out_preview.wdt_count); 1447 - pipe_wdt_cnt[i][3] += 1448 - atomic_read(&asd->video_out_video_capture.wdt_count); 1449 - css_recover = 1450 - (pipe_wdt_cnt[i][0] <= ATOMISP_ISP_MAX_TIMEOUT_COUNT && 1451 - pipe_wdt_cnt[i][1] <= ATOMISP_ISP_MAX_TIMEOUT_COUNT && 1452 - pipe_wdt_cnt[i][2] <= ATOMISP_ISP_MAX_TIMEOUT_COUNT && 1453 - pipe_wdt_cnt[i][3] <= ATOMISP_ISP_MAX_TIMEOUT_COUNT) 1454 - ? true : false; 1455 - dev_err(isp->dev, 1456 - "pipe on asd%d timeout cnt: (%d, %d, %d, %d) of %d, recover = %d\n", 1457 - asd->index, pipe_wdt_cnt[i][0], pipe_wdt_cnt[i][1], 1458 - pipe_wdt_cnt[i][2], pipe_wdt_cnt[i][3], 1459 - ATOMISP_ISP_MAX_TIMEOUT_COUNT, css_recover); 1460 - } 1461 - } 1462 - 1463 - if (css_recover) { 1464 - ia_css_debug_dump_sp_sw_debug_info(); 1465 - ia_css_debug_dump_debug_info(__func__); 1466 - for (i = 0; i < isp->num_of_streams; i++) { 1467 - struct atomisp_sub_device *asd = &isp->asd[i]; 1468 - 1469 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 1470 - continue; 1471 - dev_err(isp->dev, "%s, vdev %s buffers in css: %d\n", 1472 - __func__, 1473 - asd->video_out_capture.vdev.name, 1474 - asd->video_out_capture. 1475 - buffers_in_css); 1476 - dev_err(isp->dev, 1477 - "%s, vdev %s buffers in css: %d\n", 1478 - __func__, 1479 - asd->video_out_vf.vdev.name, 1480 - asd->video_out_vf. 1481 - buffers_in_css); 1482 - dev_err(isp->dev, 1483 - "%s, vdev %s buffers in css: %d\n", 1484 - __func__, 1485 - asd->video_out_preview.vdev.name, 1486 - asd->video_out_preview. 1487 - buffers_in_css); 1488 - dev_err(isp->dev, 1489 - "%s, vdev %s buffers in css: %d\n", 1490 - __func__, 1491 - asd->video_out_video_capture.vdev.name, 1492 - asd->video_out_video_capture. 1493 - buffers_in_css); 1494 - dev_err(isp->dev, 1495 - "%s, s3a buffers in css preview pipe:%d\n", 1496 - __func__, 1497 - asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_PREVIEW]); 1498 - dev_err(isp->dev, 1499 - "%s, s3a buffers in css capture pipe:%d\n", 1500 - __func__, 1501 - asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_CAPTURE]); 1502 - dev_err(isp->dev, 1503 - "%s, s3a buffers in css video pipe:%d\n", 1504 - __func__, 1505 - asd->s3a_bufs_in_css[IA_CSS_PIPE_ID_VIDEO]); 1506 - dev_err(isp->dev, 1507 - "%s, dis buffers in css: %d\n", 1508 - __func__, asd->dis_bufs_in_css); 1509 - dev_err(isp->dev, 1510 - "%s, metadata buffers in css preview pipe:%d\n", 1511 - __func__, 1512 - asd->metadata_bufs_in_css 1513 - [ATOMISP_INPUT_STREAM_GENERAL] 1514 - [IA_CSS_PIPE_ID_PREVIEW]); 1515 - dev_err(isp->dev, 1516 - "%s, metadata buffers in css capture pipe:%d\n", 1517 - __func__, 1518 - asd->metadata_bufs_in_css 1519 - [ATOMISP_INPUT_STREAM_GENERAL] 1520 - [IA_CSS_PIPE_ID_CAPTURE]); 1521 - dev_err(isp->dev, 1522 - "%s, metadata buffers in css video pipe:%d\n", 1523 - __func__, 1524 - asd->metadata_bufs_in_css 1525 - [ATOMISP_INPUT_STREAM_GENERAL] 1526 - [IA_CSS_PIPE_ID_VIDEO]); 1527 - if (asd->enable_raw_buffer_lock->val) { 1528 - unsigned int j; 1529 - 1530 - dev_err(isp->dev, "%s, raw_buffer_locked_count %d\n", 1531 - __func__, asd->raw_buffer_locked_count); 1532 - for (j = 0; j <= ATOMISP_MAX_EXP_ID / 32; j++) 1533 - dev_err(isp->dev, "%s, raw_buffer_bitmap[%d]: 0x%x\n", 1534 - __func__, j, 1535 - asd->raw_buffer_bitmap[j]); 1536 - } 1537 - } 1538 - 1539 - /*sh_css_dump_sp_state();*/ 1540 - /*sh_css_dump_isp_state();*/ 1541 - } else { 1542 - for (i = 0; i < isp->num_of_streams; i++) { 1543 - struct atomisp_sub_device *asd = &isp->asd[i]; 1544 - 1545 - if (asd->streaming == 1546 - ATOMISP_DEVICE_STREAMING_ENABLED) { 1547 - atomisp_clear_css_buffer_counters(asd); 1548 - atomisp_flush_bufs_and_wakeup(asd); 1549 - complete(&asd->init_done); 1550 - } 1551 - if (IS_ISP2401) 1552 - atomisp_wdt_stop(asd, false); 1553 - } 1554 - 1555 - if (!IS_ISP2401) { 1556 - atomic_set(&isp->wdt_count, 0); 1557 - } else { 1558 - isp->isp_fatal_error = true; 1559 - atomic_set(&isp->wdt_work_queued, 0); 1560 - 1561 - rt_mutex_unlock(&isp->mutex); 1562 - return; 1563 - } 1564 - } 1565 - 1462 + mutex_lock(&isp->mutex); 1566 1463 __atomisp_css_recover(isp, true); 1567 - if (IS_ISP2401) { 1568 - for (i = 0; i < isp->num_of_streams; i++) { 1569 - struct atomisp_sub_device *asd = &isp->asd[i]; 1570 - 1571 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 1572 - continue; 1573 - 1574 - atomisp_wdt_refresh(asd, 1575 - isp->sw_contex.file_input ? 1576 - ATOMISP_ISP_FILE_TIMEOUT_DURATION : 1577 - ATOMISP_ISP_TIMEOUT_DURATION); 1578 - } 1579 - } 1580 - 1581 - dev_err(isp->dev, "timeout recovery handling done\n"); 1582 - atomic_set(&isp->wdt_work_queued, 0); 1583 - 1584 - rt_mutex_unlock(&isp->mutex); 1464 + mutex_unlock(&isp->mutex); 1585 1465 } 1586 1466 1587 1467 void atomisp_css_flush(struct atomisp_device *isp) 1588 1468 { 1589 - int i; 1590 - 1591 - if (!atomisp_streaming_count(isp)) 1592 - return; 1593 - 1594 - /* Disable wdt */ 1595 - for (i = 0; i < isp->num_of_streams; i++) { 1596 - struct atomisp_sub_device *asd = &isp->asd[i]; 1597 - 1598 - atomisp_wdt_stop(asd, true); 1599 - } 1600 - 1601 1469 /* Start recover */ 1602 1470 __atomisp_css_recover(isp, false); 1603 - /* Restore wdt */ 1604 - for (i = 0; i < isp->num_of_streams; i++) { 1605 - struct atomisp_sub_device *asd = &isp->asd[i]; 1606 1471 1607 - if (asd->streaming != 1608 - ATOMISP_DEVICE_STREAMING_ENABLED) 1609 - continue; 1610 - 1611 - atomisp_wdt_refresh(asd, 1612 - isp->sw_contex.file_input ? 1613 - ATOMISP_ISP_FILE_TIMEOUT_DURATION : 1614 - ATOMISP_ISP_TIMEOUT_DURATION); 1615 - } 1616 1472 dev_dbg(isp->dev, "atomisp css flush done\n"); 1617 - } 1618 - 1619 - void atomisp_wdt(struct timer_list *t) 1620 - { 1621 - struct atomisp_sub_device *asd; 1622 - struct atomisp_device *isp; 1623 - 1624 - if (!IS_ISP2401) { 1625 - asd = from_timer(asd, t, wdt); 1626 - isp = asd->isp; 1627 - } else { 1628 - struct atomisp_video_pipe *pipe = from_timer(pipe, t, wdt); 1629 - 1630 - asd = pipe->asd; 1631 - isp = asd->isp; 1632 - 1633 - atomic_inc(&pipe->wdt_count); 1634 - dev_warn(isp->dev, 1635 - "[WARNING]asd %d pipe %s ISP timeout %d!\n", 1636 - asd->index, pipe->vdev.name, 1637 - atomic_read(&pipe->wdt_count)); 1638 - } 1639 - 1640 - if (atomic_read(&isp->wdt_work_queued)) { 1641 - dev_dbg(isp->dev, "ISP watchdog was put into workqueue\n"); 1642 - return; 1643 - } 1644 - atomic_set(&isp->wdt_work_queued, 1); 1645 - queue_work(isp->wdt_work_queue, &isp->wdt_work); 1646 - } 1647 - 1648 - /* ISP2400 */ 1649 - void atomisp_wdt_start(struct atomisp_sub_device *asd) 1650 - { 1651 - atomisp_wdt_refresh(asd, ATOMISP_ISP_TIMEOUT_DURATION); 1652 - } 1653 - 1654 - /* ISP2401 */ 1655 - void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe, 1656 - unsigned int delay) 1657 - { 1658 - unsigned long next; 1659 - 1660 - if (!pipe->asd) { 1661 - dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", 1662 - __func__, pipe->vdev.name); 1663 - return; 1664 - } 1665 - 1666 - if (delay != ATOMISP_WDT_KEEP_CURRENT_DELAY) 1667 - pipe->wdt_duration = delay; 1668 - 1669 - next = jiffies + pipe->wdt_duration; 1670 - 1671 - /* Override next if it has been pushed beyon the "next" time */ 1672 - if (atomisp_is_wdt_running(pipe) && time_after(pipe->wdt_expires, next)) 1673 - next = pipe->wdt_expires; 1674 - 1675 - pipe->wdt_expires = next; 1676 - 1677 - if (atomisp_is_wdt_running(pipe)) 1678 - dev_dbg(pipe->asd->isp->dev, "WDT will hit after %d ms (%s)\n", 1679 - ((int)(next - jiffies) * 1000 / HZ), pipe->vdev.name); 1680 - else 1681 - dev_dbg(pipe->asd->isp->dev, "WDT starts with %d ms period (%s)\n", 1682 - ((int)(next - jiffies) * 1000 / HZ), pipe->vdev.name); 1683 - 1684 - mod_timer(&pipe->wdt, next); 1685 - } 1686 - 1687 - void atomisp_wdt_refresh(struct atomisp_sub_device *asd, unsigned int delay) 1688 - { 1689 - if (!IS_ISP2401) { 1690 - unsigned long next; 1691 - 1692 - if (delay != ATOMISP_WDT_KEEP_CURRENT_DELAY) 1693 - asd->wdt_duration = delay; 1694 - 1695 - next = jiffies + asd->wdt_duration; 1696 - 1697 - /* Override next if it has been pushed beyon the "next" time */ 1698 - if (atomisp_is_wdt_running(asd) && time_after(asd->wdt_expires, next)) 1699 - next = asd->wdt_expires; 1700 - 1701 - asd->wdt_expires = next; 1702 - 1703 - if (atomisp_is_wdt_running(asd)) 1704 - dev_dbg(asd->isp->dev, "WDT will hit after %d ms\n", 1705 - ((int)(next - jiffies) * 1000 / HZ)); 1706 - else 1707 - dev_dbg(asd->isp->dev, "WDT starts with %d ms period\n", 1708 - ((int)(next - jiffies) * 1000 / HZ)); 1709 - 1710 - mod_timer(&asd->wdt, next); 1711 - atomic_set(&asd->isp->wdt_count, 0); 1712 - } else { 1713 - dev_dbg(asd->isp->dev, "WDT refresh all:\n"); 1714 - if (atomisp_is_wdt_running(&asd->video_out_capture)) 1715 - atomisp_wdt_refresh_pipe(&asd->video_out_capture, delay); 1716 - if (atomisp_is_wdt_running(&asd->video_out_preview)) 1717 - atomisp_wdt_refresh_pipe(&asd->video_out_preview, delay); 1718 - if (atomisp_is_wdt_running(&asd->video_out_vf)) 1719 - atomisp_wdt_refresh_pipe(&asd->video_out_vf, delay); 1720 - if (atomisp_is_wdt_running(&asd->video_out_video_capture)) 1721 - atomisp_wdt_refresh_pipe(&asd->video_out_video_capture, delay); 1722 - } 1723 - } 1724 - 1725 - /* ISP2401 */ 1726 - void atomisp_wdt_stop_pipe(struct atomisp_video_pipe *pipe, bool sync) 1727 - { 1728 - if (!pipe->asd) { 1729 - dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", 1730 - __func__, pipe->vdev.name); 1731 - return; 1732 - } 1733 - 1734 - if (!atomisp_is_wdt_running(pipe)) 1735 - return; 1736 - 1737 - dev_dbg(pipe->asd->isp->dev, 1738 - "WDT stop asd %d (%s)\n", pipe->asd->index, pipe->vdev.name); 1739 - 1740 - if (sync) { 1741 - del_timer_sync(&pipe->wdt); 1742 - cancel_work_sync(&pipe->asd->isp->wdt_work); 1743 - } else { 1744 - del_timer(&pipe->wdt); 1745 - } 1746 - } 1747 - 1748 - /* ISP 2401 */ 1749 - void atomisp_wdt_start_pipe(struct atomisp_video_pipe *pipe) 1750 - { 1751 - atomisp_wdt_refresh_pipe(pipe, ATOMISP_ISP_TIMEOUT_DURATION); 1752 - } 1753 - 1754 - void atomisp_wdt_stop(struct atomisp_sub_device *asd, bool sync) 1755 - { 1756 - dev_dbg(asd->isp->dev, "WDT stop:\n"); 1757 - 1758 - if (!IS_ISP2401) { 1759 - if (sync) { 1760 - del_timer_sync(&asd->wdt); 1761 - cancel_work_sync(&asd->isp->wdt_work); 1762 - } else { 1763 - del_timer(&asd->wdt); 1764 - } 1765 - } else { 1766 - atomisp_wdt_stop_pipe(&asd->video_out_capture, sync); 1767 - atomisp_wdt_stop_pipe(&asd->video_out_preview, sync); 1768 - atomisp_wdt_stop_pipe(&asd->video_out_vf, sync); 1769 - atomisp_wdt_stop_pipe(&asd->video_out_video_capture, sync); 1770 - } 1771 1473 } 1772 1474 1773 1475 void atomisp_setup_flash(struct atomisp_sub_device *asd) ··· 1508 1884 * For CSS2.0: we change the way to not dequeue all the event at one 1509 1885 * time, instead, dequue one and process one, then another 1510 1886 */ 1511 - rt_mutex_lock(&isp->mutex); 1887 + mutex_lock(&isp->mutex); 1512 1888 if (atomisp_css_isr_thread(isp, frame_done_found, css_pipe_done)) 1513 1889 goto out; 1514 1890 ··· 1519 1895 atomisp_setup_flash(asd); 1520 1896 } 1521 1897 out: 1522 - rt_mutex_unlock(&isp->mutex); 1523 - for (i = 0; i < isp->num_of_streams; i++) { 1524 - asd = &isp->asd[i]; 1525 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED 1526 - && css_pipe_done[asd->index] 1527 - && isp->sw_contex.file_input) 1528 - v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1529 - video, s_stream, 1); 1530 - } 1898 + mutex_unlock(&isp->mutex); 1531 1899 dev_dbg(isp->dev, "<%s\n", __func__); 1532 1900 1533 1901 return IRQ_HANDLED; ··· 1938 2322 { 1939 2323 struct atomisp_device *isp = asd->isp; 1940 2324 int err; 1941 - u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad); 1942 2325 1943 2326 if (atomisp_css_get_grid_info(asd, pipe_id, source_pad)) 1944 2327 return; ··· 1946 2331 the grid size. */ 1947 2332 atomisp_css_free_stat_buffers(asd); 1948 2333 1949 - err = atomisp_alloc_css_stat_bufs(asd, stream_id); 2334 + err = atomisp_alloc_css_stat_bufs(asd, ATOMISP_INPUT_STREAM_GENERAL); 1950 2335 if (err) { 1951 2336 dev_err(isp->dev, "stat_buf allocate error\n"); 1952 2337 goto err; ··· 3692 4077 unsigned long irqflags; 3693 4078 bool need_to_enqueue_buffer = false; 3694 4079 4080 + lockdep_assert_held(&asd->isp->mutex); 4081 + 3695 4082 if (!asd) { 3696 4083 dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", 3697 4084 __func__, pipe->vdev.name); ··· 3760 4143 return; 3761 4144 3762 4145 atomisp_qbuffers_to_css(asd); 3763 - 3764 - if (!IS_ISP2401) { 3765 - if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd)) 3766 - atomisp_wdt_start(asd); 3767 - } else { 3768 - if (atomisp_buffers_queued_pipe(pipe)) { 3769 - if (!atomisp_is_wdt_running(pipe)) 3770 - atomisp_wdt_start_pipe(pipe); 3771 - else 3772 - atomisp_wdt_refresh_pipe(pipe, 3773 - ATOMISP_WDT_KEEP_CURRENT_DELAY); 3774 - } 3775 - } 3776 4146 } 3777 4147 3778 4148 /* ··· 3773 4169 struct atomisp_css_params_with_list *param = NULL; 3774 4170 struct atomisp_css_params *css_param = &asd->params.css_param; 3775 4171 int ret; 4172 + 4173 + lockdep_assert_held(&asd->isp->mutex); 3776 4174 3777 4175 if (!asd) { 3778 4176 dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", ··· 4430 4824 const struct atomisp_format_bridge *fmt; 4431 4825 struct atomisp_input_stream_info *stream_info = 4432 4826 (struct atomisp_input_stream_info *)snr_mbus_fmt->reserved; 4433 - u16 stream_index; 4434 - int source_pad = atomisp_subdev_source_pad(vdev); 4435 4827 int ret; 4436 4828 4437 4829 if (!asd) { ··· 4441 4837 if (!isp->inputs[asd->input_curr].camera) 4442 4838 return -EINVAL; 4443 4839 4444 - stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); 4445 4840 fmt = atomisp_get_format_bridge(f->pixelformat); 4446 4841 if (!fmt) { 4447 4842 dev_err(isp->dev, "unsupported pixelformat!\n"); ··· 4454 4851 snr_mbus_fmt->width = f->width; 4455 4852 snr_mbus_fmt->height = f->height; 4456 4853 4457 - __atomisp_init_stream_info(stream_index, stream_info); 4854 + __atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, stream_info); 4458 4855 4459 4856 dev_dbg(isp->dev, "try_mbus_fmt: asking for %ux%u\n", 4460 4857 snr_mbus_fmt->width, snr_mbus_fmt->height); ··· 4489 4886 return 0; 4490 4887 } 4491 4888 4492 - if (snr_mbus_fmt->width < f->width 4493 - && snr_mbus_fmt->height < f->height) { 4889 + if (!res_overflow || (snr_mbus_fmt->width < f->width && 4890 + snr_mbus_fmt->height < f->height)) { 4494 4891 f->width = snr_mbus_fmt->width; 4495 4892 f->height = snr_mbus_fmt->height; 4496 4893 /* Set the flag when resolution requested is ··· 4505 4902 ATOM_ISP_MAX_WIDTH), ATOM_ISP_STEP_WIDTH); 4506 4903 f->height = rounddown(clamp_t(u32, f->height, ATOM_ISP_MIN_HEIGHT, 4507 4904 ATOM_ISP_MAX_HEIGHT), ATOM_ISP_STEP_HEIGHT); 4508 - 4509 - return 0; 4510 - } 4511 - 4512 - static int 4513 - atomisp_try_fmt_file(struct atomisp_device *isp, struct v4l2_format *f) 4514 - { 4515 - u32 width = f->fmt.pix.width; 4516 - u32 height = f->fmt.pix.height; 4517 - u32 pixelformat = f->fmt.pix.pixelformat; 4518 - enum v4l2_field field = f->fmt.pix.field; 4519 - u32 depth; 4520 - 4521 - if (!atomisp_get_format_bridge(pixelformat)) { 4522 - dev_err(isp->dev, "Wrong output pixelformat\n"); 4523 - return -EINVAL; 4524 - } 4525 - 4526 - depth = atomisp_get_pixel_depth(pixelformat); 4527 - 4528 - if (field == V4L2_FIELD_ANY) { 4529 - field = V4L2_FIELD_NONE; 4530 - } else if (field != V4L2_FIELD_NONE) { 4531 - dev_err(isp->dev, "Wrong output field\n"); 4532 - return -EINVAL; 4533 - } 4534 - 4535 - f->fmt.pix.field = field; 4536 - f->fmt.pix.width = clamp_t(u32, 4537 - rounddown(width, (u32)ATOM_ISP_STEP_WIDTH), 4538 - ATOM_ISP_MIN_WIDTH, ATOM_ISP_MAX_WIDTH); 4539 - f->fmt.pix.height = clamp_t(u32, rounddown(height, 4540 - (u32)ATOM_ISP_STEP_HEIGHT), 4541 - ATOM_ISP_MIN_HEIGHT, ATOM_ISP_MAX_HEIGHT); 4542 - f->fmt.pix.bytesperline = (width * depth) >> 3; 4543 4905 4544 4906 return 0; 4545 4907 } ··· 4739 5171 int (*configure_pp_input)(struct atomisp_sub_device *asd, 4740 5172 unsigned int width, unsigned int height) = 4741 5173 configure_pp_input_nop; 4742 - u16 stream_index; 4743 5174 const struct atomisp_in_fmt_conv *fc; 4744 5175 int ret, i; 4745 5176 ··· 4747 5180 __func__, vdev->name); 4748 5181 return -EINVAL; 4749 5182 } 4750 - stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); 4751 5183 4752 5184 v4l2_fh_init(&fh.vfh, vdev); 4753 5185 ··· 4766 5200 dev_err(isp->dev, "mipi_info is NULL\n"); 4767 5201 return -EINVAL; 4768 5202 } 4769 - if (atomisp_set_sensor_mipi_to_isp(asd, stream_index, 5203 + if (atomisp_set_sensor_mipi_to_isp(asd, ATOMISP_INPUT_STREAM_GENERAL, 4770 5204 mipi_info)) 4771 5205 return -EINVAL; 4772 5206 fc = atomisp_find_in_fmt_conv_by_atomisp_in_fmt( ··· 4850 5284 /* ISP2401 new input system need to use copy pipe */ 4851 5285 if (asd->copy_mode) { 4852 5286 pipe_id = IA_CSS_PIPE_ID_COPY; 4853 - atomisp_css_capture_enable_online(asd, stream_index, false); 5287 + atomisp_css_capture_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, false); 4854 5288 } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { 4855 5289 /* video same in continuouscapture and online modes */ 4856 5290 configure_output = atomisp_css_video_configure_output; ··· 4882 5316 pipe_id = IA_CSS_PIPE_ID_CAPTURE; 4883 5317 4884 5318 atomisp_update_capture_mode(asd); 4885 - atomisp_css_capture_enable_online(asd, stream_index, false); 5319 + atomisp_css_capture_enable_online(asd, 5320 + ATOMISP_INPUT_STREAM_GENERAL, 5321 + false); 4886 5322 } 4887 5323 } 4888 5324 } else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) { ··· 4909 5341 4910 5342 if (!asd->continuous_mode->val) 4911 5343 /* in case of ANR, force capture pipe to offline mode */ 4912 - atomisp_css_capture_enable_online(asd, stream_index, 5344 + atomisp_css_capture_enable_online(asd, ATOMISP_INPUT_STREAM_GENERAL, 4913 5345 asd->params.low_light ? 4914 5346 false : asd->params.online_process); 4915 5347 ··· 4940 5372 pipe_id = IA_CSS_PIPE_ID_YUVPP; 4941 5373 4942 5374 if (asd->copy_mode) 4943 - ret = atomisp_css_copy_configure_output(asd, stream_index, 5375 + ret = atomisp_css_copy_configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, 4944 5376 pix->width, pix->height, 4945 5377 format->planar ? pix->bytesperline : 4946 5378 pix->bytesperline * 8 / format->depth, ··· 4964 5396 return -EINVAL; 4965 5397 } 4966 5398 if (asd->copy_mode) 4967 - ret = atomisp_css_copy_get_output_frame_info(asd, stream_index, 4968 - output_info); 5399 + ret = atomisp_css_copy_get_output_frame_info(asd, 5400 + ATOMISP_INPUT_STREAM_GENERAL, 5401 + output_info); 4969 5402 else 4970 5403 ret = get_frame_info(asd, output_info); 4971 5404 if (ret) { ··· 4981 5412 ia_css_frame_free(asd->raw_output_frame); 4982 5413 asd->raw_output_frame = NULL; 4983 5414 4984 - if (!asd->continuous_mode->val && 4985 - !asd->params.online_process && !isp->sw_contex.file_input && 5415 + if (!asd->continuous_mode->val && !asd->params.online_process && 4986 5416 ia_css_frame_allocate_from_info(&asd->raw_output_frame, 4987 5417 raw_output_info)) 4988 5418 return -ENOMEM; ··· 5030 5462 src = atomisp_subdev_get_ffmt(&asd->subdev, NULL, 5031 5463 V4L2_SUBDEV_FORMAT_ACTIVE, source_pad); 5032 5464 5033 - if ((sink->code == src->code && 5034 - sink->width == f->width && 5035 - sink->height == f->height) || 5036 - ((asd->isp->inputs[asd->input_curr].type == SOC_CAMERA) && 5037 - (asd->isp->inputs[asd->input_curr].camera_caps-> 5038 - sensor[asd->sensor_curr].stream_num > 1))) 5465 + if (sink->code == src->code && sink->width == f->width && sink->height == f->height) 5039 5466 asd->copy_mode = true; 5040 5467 else 5041 5468 asd->copy_mode = false; ··· 5058 5495 struct atomisp_device *isp; 5059 5496 struct atomisp_input_stream_info *stream_info = 5060 5497 (struct atomisp_input_stream_info *)ffmt->reserved; 5061 - u16 stream_index = ATOMISP_INPUT_STREAM_GENERAL; 5062 5498 int source_pad = atomisp_subdev_source_pad(vdev); 5063 5499 struct v4l2_subdev_fh fh; 5064 5500 int ret; ··· 5072 5510 5073 5511 v4l2_fh_init(&fh.vfh, vdev); 5074 5512 5075 - stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); 5076 - 5077 5513 format = atomisp_get_format_bridge(pixelformat); 5078 5514 if (!format) 5079 5515 return -EINVAL; ··· 5084 5524 ffmt->width, ffmt->height, padding_w, padding_h, 5085 5525 dvs_env_w, dvs_env_h); 5086 5526 5087 - __atomisp_init_stream_info(stream_index, stream_info); 5527 + __atomisp_init_stream_info(ATOMISP_INPUT_STREAM_GENERAL, stream_info); 5088 5528 5089 5529 req_ffmt = ffmt; 5090 5530 ··· 5116 5556 if (ret) 5117 5557 return ret; 5118 5558 5119 - __atomisp_update_stream_env(asd, stream_index, stream_info); 5559 + __atomisp_update_stream_env(asd, ATOMISP_INPUT_STREAM_GENERAL, stream_info); 5120 5560 5121 5561 dev_dbg(isp->dev, "sensor width: %d, height: %d\n", 5122 5562 ffmt->width, ffmt->height); ··· 5140 5580 return css_input_resolution_changed(asd, ffmt); 5141 5581 } 5142 5582 5143 - int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) 5583 + int atomisp_set_fmt(struct file *file, void *unused, struct v4l2_format *f) 5144 5584 { 5585 + struct video_device *vdev = video_devdata(file); 5145 5586 struct atomisp_device *isp = video_get_drvdata(vdev); 5146 5587 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 5147 5588 struct atomisp_sub_device *asd = pipe->asd; ··· 5165 5604 struct v4l2_subdev_fh fh; 5166 5605 int ret; 5167 5606 5168 - if (!asd) { 5169 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 5170 - __func__, vdev->name); 5171 - return -EINVAL; 5172 - } 5607 + ret = atomisp_pipe_check(pipe, true); 5608 + if (ret) 5609 + return ret; 5173 5610 5174 5611 if (source_pad >= ATOMISP_SUBDEV_PADS_NUM) 5175 5612 return -EINVAL; 5176 - 5177 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { 5178 - dev_warn(isp->dev, "ISP does not support set format while at streaming!\n"); 5179 - return -EBUSY; 5180 - } 5181 5613 5182 5614 dev_dbg(isp->dev, 5183 5615 "setting resolution %ux%u on pad %u for asd%d, bytesperline %u\n", ··· 5253 5699 f->fmt.pix.height = r.height; 5254 5700 } 5255 5701 5256 - if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && 5257 - (asd->isp->inputs[asd->input_curr].type == SOC_CAMERA) && 5258 - (asd->isp->inputs[asd->input_curr].camera_caps-> 5259 - sensor[asd->sensor_curr].stream_num > 1)) { 5260 - /* For M10MO outputing YUV preview images. */ 5261 - u16 video_index = 5262 - atomisp_source_pad_to_stream_id(asd, 5263 - ATOMISP_SUBDEV_PAD_SOURCE_VIDEO); 5264 - 5265 - ret = atomisp_css_copy_get_output_frame_info(asd, 5266 - video_index, &output_info); 5267 - if (ret) { 5268 - dev_err(isp->dev, 5269 - "copy_get_output_frame_info ret %i", ret); 5270 - return -EINVAL; 5271 - } 5272 - if (!asd->yuvpp_mode) { 5273 - /* 5274 - * If viewfinder was configured into copy_mode, 5275 - * we switch to using yuvpp pipe instead. 5276 - */ 5277 - asd->yuvpp_mode = true; 5278 - ret = atomisp_css_copy_configure_output( 5279 - asd, video_index, 0, 0, 0, 0); 5280 - if (ret) { 5281 - dev_err(isp->dev, 5282 - "failed to disable copy pipe"); 5283 - return -EINVAL; 5284 - } 5285 - ret = atomisp_css_yuvpp_configure_output( 5286 - asd, video_index, 5287 - output_info.res.width, 5288 - output_info.res.height, 5289 - output_info.padded_width, 5290 - output_info.format); 5291 - if (ret) { 5292 - dev_err(isp->dev, 5293 - "failed to set up yuvpp pipe\n"); 5294 - return -EINVAL; 5295 - } 5296 - atomisp_css_video_enable_online(asd, false); 5297 - atomisp_css_preview_enable_online(asd, 5298 - ATOMISP_INPUT_STREAM_GENERAL, false); 5299 - } 5300 - atomisp_css_yuvpp_configure_viewfinder(asd, video_index, 5301 - f->fmt.pix.width, f->fmt.pix.height, 5302 - format_bridge->planar ? f->fmt.pix.bytesperline 5303 - : f->fmt.pix.bytesperline * 8 5304 - / format_bridge->depth, format_bridge->sh_fmt); 5305 - atomisp_css_yuvpp_get_viewfinder_frame_info( 5306 - asd, video_index, &output_info); 5307 - } else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) { 5702 + if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW) { 5308 5703 atomisp_css_video_configure_viewfinder(asd, 5309 5704 f->fmt.pix.width, f->fmt.pix.height, 5310 5705 format_bridge->planar ? f->fmt.pix.bytesperline ··· 5581 6078 return 0; 5582 6079 } 5583 6080 5584 - int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f) 5585 - { 5586 - struct atomisp_device *isp = video_get_drvdata(vdev); 5587 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 5588 - struct atomisp_sub_device *asd = pipe->asd; 5589 - struct v4l2_mbus_framefmt ffmt = {0}; 5590 - const struct atomisp_format_bridge *format_bridge; 5591 - struct v4l2_subdev_fh fh; 5592 - int ret; 5593 - 5594 - if (!asd) { 5595 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 5596 - __func__, vdev->name); 5597 - return -EINVAL; 5598 - } 5599 - 5600 - v4l2_fh_init(&fh.vfh, vdev); 5601 - 5602 - dev_dbg(isp->dev, "setting fmt %ux%u 0x%x for file inject\n", 5603 - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat); 5604 - ret = atomisp_try_fmt_file(isp, f); 5605 - if (ret) { 5606 - dev_err(isp->dev, "atomisp_try_fmt_file err: %d\n", ret); 5607 - return ret; 5608 - } 5609 - 5610 - format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); 5611 - if (!format_bridge) { 5612 - dev_dbg(isp->dev, "atomisp_get_format_bridge err! fmt:0x%x\n", 5613 - f->fmt.pix.pixelformat); 5614 - return -EINVAL; 5615 - } 5616 - 5617 - pipe->pix = f->fmt.pix; 5618 - atomisp_css_input_set_mode(asd, IA_CSS_INPUT_MODE_FIFO); 5619 - atomisp_css_input_configure_port(asd, 5620 - __get_mipi_port(isp, ATOMISP_CAMERA_PORT_PRIMARY), 2, 0xffff4, 5621 - 0, 0, 0, 0); 5622 - ffmt.width = f->fmt.pix.width; 5623 - ffmt.height = f->fmt.pix.height; 5624 - ffmt.code = format_bridge->mbus_code; 5625 - 5626 - atomisp_subdev_set_ffmt(&asd->subdev, fh.state, 5627 - V4L2_SUBDEV_FORMAT_ACTIVE, 5628 - ATOMISP_SUBDEV_PAD_SINK, &ffmt); 5629 - 5630 - return 0; 5631 - } 5632 - 5633 6081 int atomisp_set_shading_table(struct atomisp_sub_device *asd, 5634 6082 struct atomisp_shading_table *user_shading_table) 5635 6083 { ··· 5729 6275 { 5730 6276 struct v4l2_ctrl *c; 5731 6277 6278 + lockdep_assert_held(&asd->isp->mutex); 6279 + 5732 6280 /* 5733 6281 * In case of M10MO ZSL capture case, we need to issue a separate 5734 6282 * capture request to M10MO which will output captured jpeg image ··· 5835 6379 return 0; 5836 6380 } 5837 6381 5838 - int atomisp_source_pad_to_stream_id(struct atomisp_sub_device *asd, 5839 - uint16_t source_pad) 5840 - { 5841 - int stream_id; 5842 - struct atomisp_device *isp = asd->isp; 5843 - 5844 - if (isp->inputs[asd->input_curr].camera_caps-> 5845 - sensor[asd->sensor_curr].stream_num == 1) 5846 - return ATOMISP_INPUT_STREAM_GENERAL; 5847 - 5848 - switch (source_pad) { 5849 - case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE: 5850 - stream_id = ATOMISP_INPUT_STREAM_CAPTURE; 5851 - break; 5852 - case ATOMISP_SUBDEV_PAD_SOURCE_VF: 5853 - stream_id = ATOMISP_INPUT_STREAM_POSTVIEW; 5854 - break; 5855 - case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW: 5856 - stream_id = ATOMISP_INPUT_STREAM_PREVIEW; 5857 - break; 5858 - case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO: 5859 - stream_id = ATOMISP_INPUT_STREAM_VIDEO; 5860 - break; 5861 - default: 5862 - stream_id = ATOMISP_INPUT_STREAM_GENERAL; 5863 - } 5864 - 5865 - return stream_id; 5866 - } 5867 - 5868 6382 bool atomisp_is_vf_pipe(struct atomisp_video_pipe *pipe) 5869 6383 { 5870 6384 struct atomisp_sub_device *asd = pipe->asd; ··· 5885 6459 spin_unlock_irqrestore(&asd->raw_buffer_bitmap_lock, flags); 5886 6460 } 5887 6461 5888 - int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id) 6462 + static int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id) 5889 6463 { 5890 6464 int *bitmap, bit; 5891 6465 unsigned long flags; ··· 5975 6549 int value = *exp_id; 5976 6550 int ret; 5977 6551 6552 + lockdep_assert_held(&isp->mutex); 6553 + 5978 6554 ret = __is_raw_buffer_locked(asd, value); 5979 6555 if (ret) { 5980 6556 dev_err(isp->dev, "%s exp_id %d invalid %d.\n", __func__, value, ret); ··· 5997 6569 struct atomisp_device *isp = asd->isp; 5998 6570 int value = *exp_id; 5999 6571 int ret; 6572 + 6573 + lockdep_assert_held(&isp->mutex); 6000 6574 6001 6575 ret = __clear_raw_buffer_bitmap(asd, value); 6002 6576 if (ret) { ··· 6034 6604 { 6035 6605 if (!event || asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 6036 6606 return -EINVAL; 6607 + 6608 + lockdep_assert_held(&asd->isp->mutex); 6037 6609 6038 6610 dev_dbg(asd->isp->dev, "%s: trying to inject a fake event 0x%x\n", 6039 6611 __func__, *event); ··· 6106 6674 enum ia_css_pipe_id pipe_id; 6107 6675 struct ia_css_pipe_info p_info; 6108 6676 int ret; 6109 - 6110 - if (!asd) { 6111 - dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", 6112 - __func__, vdev->name); 6113 - return -EINVAL; 6114 - } 6115 - 6116 - if (asd->isp->inputs[asd->input_curr].camera_caps-> 6117 - sensor[asd->sensor_curr].stream_num > 1) { 6118 - /* External ISP */ 6119 - *invalid_frame_num = 0; 6120 - return 0; 6121 - } 6122 6677 6123 6678 pipe_id = atomisp_get_pipe_id(pipe); 6124 6679 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].pipes[pipe_id]) {
+2 -9
drivers/staging/media/atomisp/pci/atomisp_cmd.h
··· 54 54 unsigned int size); 55 55 struct camera_mipi_info *atomisp_to_sensor_mipi_info(struct v4l2_subdev *sd); 56 56 struct atomisp_video_pipe *atomisp_to_video_pipe(struct video_device *dev); 57 - struct atomisp_acc_pipe *atomisp_to_acc_pipe(struct video_device *dev); 58 57 int atomisp_reset(struct atomisp_device *isp); 59 58 void atomisp_flush_bufs_and_wakeup(struct atomisp_sub_device *asd); 60 59 void atomisp_clear_css_buffer_counters(struct atomisp_sub_device *asd); ··· 65 66 /* Interrupt functions */ 66 67 void atomisp_msi_irq_init(struct atomisp_device *isp); 67 68 void atomisp_msi_irq_uninit(struct atomisp_device *isp); 68 - void atomisp_wdt_work(struct work_struct *work); 69 - void atomisp_wdt(struct timer_list *t); 69 + void atomisp_assert_recovery_work(struct work_struct *work); 70 70 void atomisp_setup_flash(struct atomisp_sub_device *asd); 71 71 irqreturn_t atomisp_isr(int irq, void *dev); 72 72 irqreturn_t atomisp_isr_thread(int irq, void *isp_ptr); ··· 266 268 int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, 267 269 bool *res_overflow); 268 270 269 - int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f); 270 - int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f); 271 + int atomisp_set_fmt(struct file *file, void *fh, struct v4l2_format *f); 271 272 272 273 int atomisp_set_shading_table(struct atomisp_sub_device *asd, 273 274 struct atomisp_shading_table *shading_table); ··· 297 300 bool q_buffers, enum atomisp_input_stream_id stream_id); 298 301 299 302 void atomisp_css_flush(struct atomisp_device *isp); 300 - int atomisp_source_pad_to_stream_id(struct atomisp_sub_device *asd, 301 - uint16_t source_pad); 302 303 303 304 /* Events. Only one event has to be exported for now. */ 304 305 void atomisp_eof_event(struct atomisp_sub_device *asd, uint8_t exp_id); ··· 319 324 int atomisp_exp_id_unlock(struct atomisp_sub_device *asd, int *exp_id); 320 325 int atomisp_exp_id_capture(struct atomisp_sub_device *asd, int *exp_id); 321 326 322 - /* Function to update Raw Buffer bitmap */ 323 - int atomisp_set_raw_buffer_bitmap(struct atomisp_sub_device *asd, int exp_id); 324 327 void atomisp_init_raw_buffer_bitmap(struct atomisp_sub_device *asd); 325 328 326 329 /* Function to enable/disable zoom for capture pipe */
-10
drivers/staging/media/atomisp/pci/atomisp_compat.h
··· 129 129 130 130 void atomisp_free_metadata_output_buf(struct atomisp_sub_device *asd); 131 131 132 - void atomisp_css_get_dis_statistics(struct atomisp_sub_device *asd, 133 - struct atomisp_css_buffer *isp_css_buffer, 134 - struct ia_css_isp_dvs_statistics_map *dvs_map); 135 - 136 132 void atomisp_css_temp_pipe_to_pipe_id(struct atomisp_sub_device *asd, 137 133 struct atomisp_css_event *current_event); 138 134 ··· 430 434 431 435 void atomisp_css_morph_table_free(struct ia_css_morph_table *table); 432 436 433 - void atomisp_css_set_cont_prev_start_time(struct atomisp_device *isp, 434 - unsigned int overlap); 435 - 436 437 int atomisp_css_get_dis_stat(struct atomisp_sub_device *asd, 437 438 struct atomisp_dis_statistics *stats); 438 439 439 440 int atomisp_css_update_stream(struct atomisp_sub_device *asd); 440 - 441 - struct atomisp_acc_fw; 442 - int atomisp_css_set_acc_parameters(struct atomisp_acc_fw *acc_fw); 443 441 444 442 int atomisp_css_isr_thread(struct atomisp_device *isp, 445 443 bool *frame_done_found,
+9 -91
drivers/staging/media/atomisp/pci/atomisp_compat_css20.c
··· 1427 1427 struct ia_css_pipe_info p_info; 1428 1428 struct ia_css_grid_info old_info; 1429 1429 struct atomisp_device *isp = asd->isp; 1430 - int stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); 1431 1430 int md_width = asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]. 1432 1431 stream_config.metadata_config.resolution.width; 1433 1432 ··· 1434 1435 memset(&old_info, 0, sizeof(struct ia_css_grid_info)); 1435 1436 1436 1437 if (ia_css_pipe_get_info( 1437 - asd->stream_env[stream_index].pipes[pipe_id], 1438 + asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].pipes[pipe_id], 1438 1439 &p_info) != 0) { 1439 1440 dev_err(isp->dev, "ia_css_pipe_get_info failed\n"); 1440 1441 return -EINVAL; ··· 1570 1571 kvfree(asd->params.metadata_user[i]); 1571 1572 asd->params.metadata_user[i] = NULL; 1572 1573 } 1573 - } 1574 - } 1575 - 1576 - void atomisp_css_get_dis_statistics(struct atomisp_sub_device *asd, 1577 - struct atomisp_css_buffer *isp_css_buffer, 1578 - struct ia_css_isp_dvs_statistics_map *dvs_map) 1579 - { 1580 - if (asd->params.dvs_stat) { 1581 - if (dvs_map) 1582 - ia_css_translate_dvs2_statistics( 1583 - asd->params.dvs_stat, dvs_map); 1584 - else 1585 - ia_css_get_dvs2_statistics(asd->params.dvs_stat, 1586 - isp_css_buffer->css_buffer.data.stats_dvs); 1587 1574 } 1588 1575 } 1589 1576 ··· 2679 2694 struct atomisp_device *isp = asd->isp; 2680 2695 2681 2696 if (ATOMISP_SOC_CAMERA(asd)) { 2682 - stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); 2697 + stream_index = ATOMISP_INPUT_STREAM_GENERAL; 2683 2698 } else { 2684 2699 stream_index = (pipe_index == IA_CSS_PIPE_ID_YUVPP) ? 2685 2700 ATOMISP_INPUT_STREAM_VIDEO : 2686 - atomisp_source_pad_to_stream_id(asd, source_pad); 2701 + ATOMISP_INPUT_STREAM_GENERAL; 2687 2702 } 2688 2703 2689 2704 if (0 != ia_css_pipe_get_info(asd->stream_env[stream_index] ··· 3611 3626 struct atomisp_dis_buf *dis_buf; 3612 3627 unsigned long flags; 3613 3628 3629 + lockdep_assert_held(&isp->mutex); 3630 + 3614 3631 if (!asd->params.dvs_stat->hor_prod.odd_real || 3615 3632 !asd->params.dvs_stat->hor_prod.odd_imag || 3616 3633 !asd->params.dvs_stat->hor_prod.even_real || ··· 3624 3637 return -EINVAL; 3625 3638 3626 3639 /* isp needs to be streaming to get DIS statistics */ 3627 - spin_lock_irqsave(&isp->lock, flags); 3628 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) { 3629 - spin_unlock_irqrestore(&isp->lock, flags); 3640 + if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 3630 3641 return -EINVAL; 3631 - } 3632 - spin_unlock_irqrestore(&isp->lock, flags); 3633 3642 3634 3643 if (atomisp_compare_dvs_grid(asd, &stats->dvs2_stat.grid_info) != 0) 3635 3644 /* If the grid info in the argument differs from the current ··· 3746 3763 ia_css_morph_table_free(table); 3747 3764 } 3748 3765 3749 - void atomisp_css_set_cont_prev_start_time(struct atomisp_device *isp, 3750 - unsigned int overlap) 3751 - { 3752 - /* CSS 2.0 doesn't support this API. */ 3753 - dev_dbg(isp->dev, "set cont prev start time is not supported.\n"); 3754 - return; 3755 - } 3756 - 3757 - /* Set the ACC binary arguments */ 3758 - int atomisp_css_set_acc_parameters(struct atomisp_acc_fw *acc_fw) 3759 - { 3760 - unsigned int mem; 3761 - 3762 - for (mem = 0; mem < ATOMISP_ACC_NR_MEMORY; mem++) { 3763 - if (acc_fw->args[mem].length == 0) 3764 - continue; 3765 - 3766 - ia_css_isp_param_set_css_mem_init(&acc_fw->fw->mem_initializers, 3767 - IA_CSS_PARAM_CLASS_PARAM, mem, 3768 - acc_fw->args[mem].css_ptr, 3769 - acc_fw->args[mem].length); 3770 - } 3771 - 3772 - return 0; 3773 - } 3774 - 3775 3766 static struct atomisp_sub_device *__get_atomisp_subdev( 3776 3767 struct ia_css_pipe *css_pipe, 3777 3768 struct atomisp_device *isp, ··· 3781 3824 enum atomisp_input_stream_id stream_id = 0; 3782 3825 struct atomisp_css_event current_event; 3783 3826 struct atomisp_sub_device *asd; 3784 - bool reset_wdt_timer[MAX_STREAM_NUM] = {false}; 3785 - int i; 3827 + 3828 + lockdep_assert_held(&isp->mutex); 3786 3829 3787 3830 while (!ia_css_dequeue_psys_event(&current_event.event)) { 3788 3831 if (current_event.event.type == ··· 3796 3839 __func__, 3797 3840 current_event.event.fw_assert_module_id, 3798 3841 current_event.event.fw_assert_line_no); 3799 - for (i = 0; i < isp->num_of_streams; i++) 3800 - atomisp_wdt_stop(&isp->asd[i], 0); 3801 3842 3802 - if (!IS_ISP2401) 3803 - atomisp_wdt(&isp->asd[0].wdt); 3804 - else 3805 - queue_work(isp->wdt_work_queue, &isp->wdt_work); 3806 - 3843 + queue_work(system_long_wq, &isp->assert_recovery_work); 3807 3844 return -EINVAL; 3808 3845 } else if (current_event.event.type == IA_CSS_EVENT_TYPE_FW_WARNING) { 3809 3846 dev_warn(isp->dev, "%s: ISP reports warning, code is %d, exp_id %d\n", ··· 3826 3875 frame_done_found[asd->index] = true; 3827 3876 atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, 3828 3877 current_event.pipe, true, stream_id); 3829 - 3830 - if (!IS_ISP2401) 3831 - reset_wdt_timer[asd->index] = true; /* ISP running */ 3832 - 3833 3878 break; 3834 3879 case IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE: 3835 3880 dev_dbg(isp->dev, "event: Second output frame done"); 3836 3881 frame_done_found[asd->index] = true; 3837 3882 atomisp_buf_done(asd, 0, IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME, 3838 3883 current_event.pipe, true, stream_id); 3839 - 3840 - if (!IS_ISP2401) 3841 - reset_wdt_timer[asd->index] = true; /* ISP running */ 3842 - 3843 3884 break; 3844 3885 case IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE: 3845 3886 dev_dbg(isp->dev, "event: 3A stats frame done"); ··· 3852 3909 atomisp_buf_done(asd, 0, 3853 3910 IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, 3854 3911 current_event.pipe, true, stream_id); 3855 - 3856 - if (!IS_ISP2401) 3857 - reset_wdt_timer[asd->index] = true; /* ISP running */ 3858 - 3859 3912 break; 3860 3913 case IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE: 3861 3914 dev_dbg(isp->dev, "event: second VF output frame done"); 3862 3915 atomisp_buf_done(asd, 0, 3863 3916 IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME, 3864 3917 current_event.pipe, true, stream_id); 3865 - if (!IS_ISP2401) 3866 - reset_wdt_timer[asd->index] = true; /* ISP running */ 3867 - 3868 3918 break; 3869 3919 case IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE: 3870 3920 dev_dbg(isp->dev, "event: dis stats frame done"); ··· 3878 3942 current_event.event.type); 3879 3943 break; 3880 3944 } 3881 - } 3882 - 3883 - if (IS_ISP2401) 3884 - return 0; 3885 - 3886 - /* ISP2400: If there are no buffers queued then delete wdt timer. */ 3887 - for (i = 0; i < isp->num_of_streams; i++) { 3888 - asd = &isp->asd[i]; 3889 - if (!asd) 3890 - continue; 3891 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 3892 - continue; 3893 - if (!atomisp_buffers_queued(asd)) 3894 - atomisp_wdt_stop(asd, false); 3895 - else if (reset_wdt_timer[i]) 3896 - /* SOF irq should not reset wdt timer. */ 3897 - atomisp_wdt_refresh(asd, 3898 - ATOMISP_WDT_KEEP_CURRENT_DELAY); 3899 3945 } 3900 3946 3901 3947 return 0;
-229
drivers/staging/media/atomisp/pci/atomisp_file.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Support for Medifield PNW Camera Imaging ISP subsystem. 4 - * 5 - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. 6 - * 7 - * Copyright (c) 2010 Silicon Hive www.siliconhive.com. 8 - * 9 - * This program is free software; you can redistribute it and/or 10 - * modify it under the terms of the GNU General Public License version 11 - * 2 as published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * 19 - */ 20 - 21 - #include <media/v4l2-event.h> 22 - #include <media/v4l2-mediabus.h> 23 - 24 - #include <media/videobuf-vmalloc.h> 25 - #include <linux/delay.h> 26 - 27 - #include "ia_css.h" 28 - 29 - #include "atomisp_cmd.h" 30 - #include "atomisp_common.h" 31 - #include "atomisp_file.h" 32 - #include "atomisp_internal.h" 33 - #include "atomisp_ioctl.h" 34 - 35 - static void file_work(struct work_struct *work) 36 - { 37 - struct atomisp_file_device *file_dev = 38 - container_of(work, struct atomisp_file_device, work); 39 - struct atomisp_device *isp = file_dev->isp; 40 - /* only support file injection on subdev0 */ 41 - struct atomisp_sub_device *asd = &isp->asd[0]; 42 - struct atomisp_video_pipe *out_pipe = &asd->video_in; 43 - unsigned short *buf = videobuf_to_vmalloc(out_pipe->outq.bufs[0]); 44 - struct v4l2_mbus_framefmt isp_sink_fmt; 45 - 46 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 47 - return; 48 - 49 - dev_dbg(isp->dev, ">%s: ready to start streaming\n", __func__); 50 - isp_sink_fmt = *atomisp_subdev_get_ffmt(&asd->subdev, NULL, 51 - V4L2_SUBDEV_FORMAT_ACTIVE, 52 - ATOMISP_SUBDEV_PAD_SINK); 53 - 54 - while (!ia_css_isp_has_started()) 55 - usleep_range(1000, 1500); 56 - 57 - ia_css_stream_send_input_frame(asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream, 58 - buf, isp_sink_fmt.width, 59 - isp_sink_fmt.height); 60 - dev_dbg(isp->dev, "<%s: streaming done\n", __func__); 61 - } 62 - 63 - static int file_input_s_stream(struct v4l2_subdev *sd, int enable) 64 - { 65 - struct atomisp_file_device *file_dev = v4l2_get_subdevdata(sd); 66 - struct atomisp_device *isp = file_dev->isp; 67 - /* only support file injection on subdev0 */ 68 - struct atomisp_sub_device *asd = &isp->asd[0]; 69 - 70 - dev_dbg(isp->dev, "%s: enable %d\n", __func__, enable); 71 - if (enable) { 72 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_ENABLED) 73 - return 0; 74 - 75 - queue_work(file_dev->work_queue, &file_dev->work); 76 - return 0; 77 - } 78 - cancel_work_sync(&file_dev->work); 79 - return 0; 80 - } 81 - 82 - static int file_input_get_fmt(struct v4l2_subdev *sd, 83 - struct v4l2_subdev_state *sd_state, 84 - struct v4l2_subdev_format *format) 85 - { 86 - struct v4l2_mbus_framefmt *fmt = &format->format; 87 - struct atomisp_file_device *file_dev = v4l2_get_subdevdata(sd); 88 - struct atomisp_device *isp = file_dev->isp; 89 - /* only support file injection on subdev0 */ 90 - struct atomisp_sub_device *asd = &isp->asd[0]; 91 - struct v4l2_mbus_framefmt *isp_sink_fmt; 92 - 93 - if (format->pad) 94 - return -EINVAL; 95 - isp_sink_fmt = atomisp_subdev_get_ffmt(&asd->subdev, NULL, 96 - V4L2_SUBDEV_FORMAT_ACTIVE, 97 - ATOMISP_SUBDEV_PAD_SINK); 98 - 99 - fmt->width = isp_sink_fmt->width; 100 - fmt->height = isp_sink_fmt->height; 101 - fmt->code = isp_sink_fmt->code; 102 - 103 - return 0; 104 - } 105 - 106 - static int file_input_set_fmt(struct v4l2_subdev *sd, 107 - struct v4l2_subdev_state *sd_state, 108 - struct v4l2_subdev_format *format) 109 - { 110 - struct v4l2_mbus_framefmt *fmt = &format->format; 111 - 112 - if (format->pad) 113 - return -EINVAL; 114 - file_input_get_fmt(sd, sd_state, format); 115 - if (format->which == V4L2_SUBDEV_FORMAT_TRY) 116 - sd_state->pads->try_fmt = *fmt; 117 - return 0; 118 - } 119 - 120 - static int file_input_log_status(struct v4l2_subdev *sd) 121 - { 122 - /*to fake*/ 123 - return 0; 124 - } 125 - 126 - static int file_input_s_power(struct v4l2_subdev *sd, int on) 127 - { 128 - /* to fake */ 129 - return 0; 130 - } 131 - 132 - static int file_input_enum_mbus_code(struct v4l2_subdev *sd, 133 - struct v4l2_subdev_state *sd_state, 134 - struct v4l2_subdev_mbus_code_enum *code) 135 - { 136 - /*to fake*/ 137 - return 0; 138 - } 139 - 140 - static int file_input_enum_frame_size(struct v4l2_subdev *sd, 141 - struct v4l2_subdev_state *sd_state, 142 - struct v4l2_subdev_frame_size_enum *fse) 143 - { 144 - /*to fake*/ 145 - return 0; 146 - } 147 - 148 - static int file_input_enum_frame_ival(struct v4l2_subdev *sd, 149 - struct v4l2_subdev_state *sd_state, 150 - struct v4l2_subdev_frame_interval_enum 151 - *fie) 152 - { 153 - /*to fake*/ 154 - return 0; 155 - } 156 - 157 - static const struct v4l2_subdev_video_ops file_input_video_ops = { 158 - .s_stream = file_input_s_stream, 159 - }; 160 - 161 - static const struct v4l2_subdev_core_ops file_input_core_ops = { 162 - .log_status = file_input_log_status, 163 - .s_power = file_input_s_power, 164 - }; 165 - 166 - static const struct v4l2_subdev_pad_ops file_input_pad_ops = { 167 - .enum_mbus_code = file_input_enum_mbus_code, 168 - .enum_frame_size = file_input_enum_frame_size, 169 - .enum_frame_interval = file_input_enum_frame_ival, 170 - .get_fmt = file_input_get_fmt, 171 - .set_fmt = file_input_set_fmt, 172 - }; 173 - 174 - static const struct v4l2_subdev_ops file_input_ops = { 175 - .core = &file_input_core_ops, 176 - .video = &file_input_video_ops, 177 - .pad = &file_input_pad_ops, 178 - }; 179 - 180 - void 181 - atomisp_file_input_unregister_entities(struct atomisp_file_device *file_dev) 182 - { 183 - media_entity_cleanup(&file_dev->sd.entity); 184 - v4l2_device_unregister_subdev(&file_dev->sd); 185 - } 186 - 187 - int atomisp_file_input_register_entities(struct atomisp_file_device *file_dev, 188 - struct v4l2_device *vdev) 189 - { 190 - /* Register the subdev and video nodes. */ 191 - return v4l2_device_register_subdev(vdev, &file_dev->sd); 192 - } 193 - 194 - void atomisp_file_input_cleanup(struct atomisp_device *isp) 195 - { 196 - struct atomisp_file_device *file_dev = &isp->file_dev; 197 - 198 - if (file_dev->work_queue) { 199 - destroy_workqueue(file_dev->work_queue); 200 - file_dev->work_queue = NULL; 201 - } 202 - } 203 - 204 - int atomisp_file_input_init(struct atomisp_device *isp) 205 - { 206 - struct atomisp_file_device *file_dev = &isp->file_dev; 207 - struct v4l2_subdev *sd = &file_dev->sd; 208 - struct media_pad *pads = file_dev->pads; 209 - struct media_entity *me = &sd->entity; 210 - 211 - file_dev->isp = isp; 212 - file_dev->work_queue = alloc_workqueue(isp->v4l2_dev.name, 0, 1); 213 - if (!file_dev->work_queue) { 214 - dev_err(isp->dev, "Failed to initialize file inject workq\n"); 215 - return -ENOMEM; 216 - } 217 - 218 - INIT_WORK(&file_dev->work, file_work); 219 - 220 - v4l2_subdev_init(sd, &file_input_ops); 221 - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 222 - strscpy(sd->name, "file_input_subdev", sizeof(sd->name)); 223 - v4l2_set_subdevdata(sd, file_dev); 224 - 225 - pads[0].flags = MEDIA_PAD_FL_SINK; 226 - me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; 227 - 228 - return media_entity_pads_init(me, 1, pads); 229 - }
-44
drivers/staging/media/atomisp/pci/atomisp_file.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * Support for Medifield PNW Camera Imaging ISP subsystem. 4 - * 5 - * Copyright (c) 2010 Intel Corporation. All Rights Reserved. 6 - * 7 - * Copyright (c) 2010 Silicon Hive www.siliconhive.com. 8 - * 9 - * This program is free software; you can redistribute it and/or 10 - * modify it under the terms of the GNU General Public License version 11 - * 2 as published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, 14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 - * GNU General Public License for more details. 17 - * 18 - * 19 - */ 20 - 21 - #ifndef __ATOMISP_FILE_H__ 22 - #define __ATOMISP_FILE_H__ 23 - 24 - #include <media/media-entity.h> 25 - #include <media/v4l2-subdev.h> 26 - 27 - struct atomisp_device; 28 - 29 - struct atomisp_file_device { 30 - struct v4l2_subdev sd; 31 - struct atomisp_device *isp; 32 - struct media_pad pads[1]; 33 - 34 - struct workqueue_struct *work_queue; 35 - struct work_struct work; 36 - }; 37 - 38 - void atomisp_file_input_cleanup(struct atomisp_device *isp); 39 - int atomisp_file_input_init(struct atomisp_device *isp); 40 - void atomisp_file_input_unregister_entities( 41 - struct atomisp_file_device *file_dev); 42 - int atomisp_file_input_register_entities(struct atomisp_file_device *file_dev, 43 - struct v4l2_device *vdev); 44 - #endif /* __ATOMISP_FILE_H__ */
+39 -235
drivers/staging/media/atomisp/pci/atomisp_fops.c
··· 369 369 return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME; 370 370 } 371 371 372 - static int atomisp_qbuffers_to_css_for_all_pipes(struct atomisp_sub_device *asd) 373 - { 374 - enum ia_css_buffer_type buf_type; 375 - enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_COPY; 376 - enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_COPY; 377 - enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_COPY; 378 - enum atomisp_input_stream_id input_stream_id; 379 - struct atomisp_video_pipe *capture_pipe; 380 - struct atomisp_video_pipe *preview_pipe; 381 - struct atomisp_video_pipe *video_pipe; 382 - 383 - capture_pipe = &asd->video_out_capture; 384 - preview_pipe = &asd->video_out_preview; 385 - video_pipe = &asd->video_out_video_capture; 386 - 387 - buf_type = atomisp_get_css_buf_type( 388 - asd, css_preview_pipe_id, 389 - atomisp_subdev_source_pad(&preview_pipe->vdev)); 390 - input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW; 391 - atomisp_q_video_buffers_to_css(asd, preview_pipe, 392 - input_stream_id, 393 - buf_type, css_preview_pipe_id); 394 - 395 - buf_type = atomisp_get_css_buf_type(asd, css_capture_pipe_id, 396 - atomisp_subdev_source_pad(&capture_pipe->vdev)); 397 - input_stream_id = ATOMISP_INPUT_STREAM_GENERAL; 398 - atomisp_q_video_buffers_to_css(asd, capture_pipe, 399 - input_stream_id, 400 - buf_type, css_capture_pipe_id); 401 - 402 - buf_type = atomisp_get_css_buf_type(asd, css_video_pipe_id, 403 - atomisp_subdev_source_pad(&video_pipe->vdev)); 404 - input_stream_id = ATOMISP_INPUT_STREAM_VIDEO; 405 - atomisp_q_video_buffers_to_css(asd, video_pipe, 406 - input_stream_id, 407 - buf_type, css_video_pipe_id); 408 - return 0; 409 - } 410 - 411 372 /* queue all available buffers to css */ 412 373 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd) 413 374 { ··· 383 422 struct atomisp_video_pipe *video_pipe = NULL; 384 423 bool raw_mode = atomisp_is_mbuscode_raw( 385 424 asd->fmt[asd->capture_pad].fmt.code); 386 - 387 - if (asd->isp->inputs[asd->input_curr].camera_caps-> 388 - sensor[asd->sensor_curr].stream_num == 2 && 389 - !asd->yuvpp_mode) 390 - return atomisp_qbuffers_to_css_for_all_pipes(asd); 391 425 392 426 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { 393 427 video_pipe = &asd->video_out_video_capture; ··· 549 593 atomisp_videobuf_free_buf(vb); 550 594 } 551 595 552 - static int atomisp_buf_setup_output(struct videobuf_queue *vq, 553 - unsigned int *count, unsigned int *size) 554 - { 555 - struct atomisp_video_pipe *pipe = vq->priv_data; 556 - 557 - *size = pipe->pix.sizeimage; 558 - 559 - return 0; 560 - } 561 - 562 - static int atomisp_buf_prepare_output(struct videobuf_queue *vq, 563 - struct videobuf_buffer *vb, 564 - enum v4l2_field field) 565 - { 566 - struct atomisp_video_pipe *pipe = vq->priv_data; 567 - 568 - vb->size = pipe->pix.sizeimage; 569 - vb->width = pipe->pix.width; 570 - vb->height = pipe->pix.height; 571 - vb->field = field; 572 - vb->state = VIDEOBUF_PREPARED; 573 - 574 - return 0; 575 - } 576 - 577 - static void atomisp_buf_queue_output(struct videobuf_queue *vq, 578 - struct videobuf_buffer *vb) 579 - { 580 - struct atomisp_video_pipe *pipe = vq->priv_data; 581 - 582 - list_add_tail(&vb->queue, &pipe->activeq_out); 583 - vb->state = VIDEOBUF_QUEUED; 584 - } 585 - 586 - static void atomisp_buf_release_output(struct videobuf_queue *vq, 587 - struct videobuf_buffer *vb) 588 - { 589 - videobuf_vmalloc_free(vb); 590 - vb->state = VIDEOBUF_NEEDS_INIT; 591 - } 592 - 593 596 static const struct videobuf_queue_ops videobuf_qops = { 594 597 .buf_setup = atomisp_buf_setup, 595 598 .buf_prepare = atomisp_buf_prepare, 596 599 .buf_queue = atomisp_buf_queue, 597 600 .buf_release = atomisp_buf_release, 598 - }; 599 - 600 - static const struct videobuf_queue_ops videobuf_qops_output = { 601 - .buf_setup = atomisp_buf_setup_output, 602 - .buf_prepare = atomisp_buf_prepare_output, 603 - .buf_queue = atomisp_buf_queue_output, 604 - .buf_release = atomisp_buf_release_output, 605 601 }; 606 602 607 603 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe) ··· 568 660 sizeof(struct atomisp_buffer), pipe, 569 661 NULL); /* ext_lock: NULL */ 570 662 571 - videobuf_queue_vmalloc_init(&pipe->outq, &videobuf_qops_output, NULL, 572 - &pipe->irq_lock, 573 - V4L2_BUF_TYPE_VIDEO_OUTPUT, 574 - V4L2_FIELD_NONE, 575 - sizeof(struct atomisp_buffer), pipe, 576 - NULL); /* ext_lock: NULL */ 577 - 578 663 INIT_LIST_HEAD(&pipe->activeq); 579 - INIT_LIST_HEAD(&pipe->activeq_out); 580 664 INIT_LIST_HEAD(&pipe->buffers_waiting_for_param); 581 665 INIT_LIST_HEAD(&pipe->per_frame_params); 582 666 memset(pipe->frame_request_config_id, 0, ··· 584 684 { 585 685 unsigned int i; 586 686 587 - isp->sw_contex.file_input = false; 588 687 isp->need_gfx_throttle = true; 589 688 isp->isp_fatal_error = false; 590 689 isp->mipi_frame_size = 0; ··· 640 741 return asd->video_out_preview.users + 641 742 asd->video_out_vf.users + 642 743 asd->video_out_capture.users + 643 - asd->video_out_video_capture.users + 644 - asd->video_acc.users + 645 - asd->video_in.users; 744 + asd->video_out_video_capture.users; 646 745 } 647 746 648 747 unsigned int atomisp_dev_users(struct atomisp_device *isp) ··· 657 760 { 658 761 struct video_device *vdev = video_devdata(file); 659 762 struct atomisp_device *isp = video_get_drvdata(vdev); 660 - struct atomisp_video_pipe *pipe = NULL; 661 - struct atomisp_acc_pipe *acc_pipe = NULL; 662 - struct atomisp_sub_device *asd; 663 - bool acc_node = false; 763 + struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 764 + struct atomisp_sub_device *asd = pipe->asd; 664 765 int ret; 665 766 666 767 dev_dbg(isp->dev, "open device %s\n", vdev->name); 667 768 668 - /* 669 - * Ensure that if we are still loading we block. Once the loading 670 - * is over we can proceed. We can't blindly hold the lock until 671 - * that occurs as if the load fails we'll deadlock the unload 672 - */ 673 - rt_mutex_lock(&isp->loading); 674 - /* 675 - * FIXME: revisit this with a better check once the code structure 676 - * is cleaned up a bit more 677 - */ 678 769 ret = v4l2_fh_open(file); 679 - if (ret) { 680 - dev_err(isp->dev, 681 - "%s: v4l2_fh_open() returned error %d\n", 682 - __func__, ret); 683 - rt_mutex_unlock(&isp->loading); 770 + if (ret) 684 771 return ret; 685 - } 686 - if (!isp->ready) { 687 - rt_mutex_unlock(&isp->loading); 688 - return -ENXIO; 689 - } 690 - rt_mutex_unlock(&isp->loading); 691 772 692 - rt_mutex_lock(&isp->mutex); 773 + mutex_lock(&isp->mutex); 693 774 694 - acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC"); 695 - if (acc_node) { 696 - acc_pipe = atomisp_to_acc_pipe(vdev); 697 - asd = acc_pipe->asd; 698 - } else { 699 - pipe = atomisp_to_video_pipe(vdev); 700 - asd = pipe->asd; 701 - } 702 775 asd->subdev.devnode = vdev; 703 776 /* Deferred firmware loading case. */ 704 777 if (isp->css_env.isp_css_fw.bytes == 0) { ··· 690 823 isp->css_env.isp_css_fw.data = NULL; 691 824 } 692 825 693 - if (acc_node && acc_pipe->users) { 694 - dev_dbg(isp->dev, "acc node already opened\n"); 695 - rt_mutex_unlock(&isp->mutex); 696 - return -EBUSY; 697 - } else if (acc_node) { 698 - goto dev_init; 699 - } 700 - 701 826 if (!isp->input_cnt) { 702 827 dev_err(isp->dev, "no camera attached\n"); 703 828 ret = -EINVAL; ··· 701 842 */ 702 843 if (pipe->users) { 703 844 dev_dbg(isp->dev, "video node already opened\n"); 704 - rt_mutex_unlock(&isp->mutex); 845 + mutex_unlock(&isp->mutex); 705 846 return -EBUSY; 706 847 } 707 848 ··· 709 850 if (ret) 710 851 goto error; 711 852 712 - dev_init: 713 853 if (atomisp_dev_users(isp)) { 714 854 dev_dbg(isp->dev, "skip init isp in open\n"); 715 855 goto init_subdev; ··· 743 885 atomisp_subdev_init_struct(asd); 744 886 745 887 done: 746 - 747 - if (acc_node) 748 - acc_pipe->users++; 749 - else 750 - pipe->users++; 751 - rt_mutex_unlock(&isp->mutex); 888 + pipe->users++; 889 + mutex_unlock(&isp->mutex); 752 890 753 891 /* Ensure that a mode is set */ 754 - if (!acc_node) 755 - v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode); 892 + v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode); 756 893 757 894 return 0; 758 895 ··· 755 902 atomisp_css_uninit(isp); 756 903 pm_runtime_put(vdev->v4l2_dev->dev); 757 904 error: 758 - rt_mutex_unlock(&isp->mutex); 905 + mutex_unlock(&isp->mutex); 906 + v4l2_fh_release(file); 759 907 return ret; 760 908 } 761 909 ··· 764 910 { 765 911 struct video_device *vdev = video_devdata(file); 766 912 struct atomisp_device *isp = video_get_drvdata(vdev); 767 - struct atomisp_video_pipe *pipe; 768 - struct atomisp_acc_pipe *acc_pipe; 769 - struct atomisp_sub_device *asd; 770 - bool acc_node; 913 + struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 914 + struct atomisp_sub_device *asd = pipe->asd; 771 915 struct v4l2_requestbuffers req; 772 916 struct v4l2_subdev_fh fh; 773 917 struct v4l2_rect clear_compose = {0}; 918 + unsigned long flags; 774 919 int ret = 0; 775 920 776 921 v4l2_fh_init(&fh.vfh, vdev); ··· 778 925 if (!isp) 779 926 return -EBADF; 780 927 781 - mutex_lock(&isp->streamoff_mutex); 782 - rt_mutex_lock(&isp->mutex); 928 + mutex_lock(&isp->mutex); 783 929 784 930 dev_dbg(isp->dev, "release device %s\n", vdev->name); 785 - acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC"); 786 - if (acc_node) { 787 - acc_pipe = atomisp_to_acc_pipe(vdev); 788 - asd = acc_pipe->asd; 789 - } else { 790 - pipe = atomisp_to_video_pipe(vdev); 791 - asd = pipe->asd; 792 - } 931 + 793 932 asd->subdev.devnode = vdev; 794 - if (acc_node) { 795 - acc_pipe->users--; 796 - goto subdev_uninit; 797 - } 933 + 798 934 pipe->users--; 799 935 800 936 if (pipe->capq.streaming) ··· 792 950 __func__); 793 951 794 952 if (pipe->capq.streaming && 795 - __atomisp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE)) { 796 - dev_err(isp->dev, 797 - "atomisp_streamoff failed on release, driver bug"); 953 + atomisp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE)) { 954 + dev_err(isp->dev, "atomisp_streamoff failed on release, driver bug"); 798 955 goto done; 799 956 } 800 957 801 958 if (pipe->users) 802 959 goto done; 803 960 804 - if (__atomisp_reqbufs(file, NULL, &req)) { 805 - dev_err(isp->dev, 806 - "atomisp_reqbufs failed on release, driver bug"); 961 + if (atomisp_reqbufs(file, NULL, &req)) { 962 + dev_err(isp->dev, "atomisp_reqbufs failed on release, driver bug"); 807 963 goto done; 808 - } 809 - 810 - if (pipe->outq.bufs[0]) { 811 - mutex_lock(&pipe->outq.vb_lock); 812 - videobuf_queue_cancel(&pipe->outq); 813 - mutex_unlock(&pipe->outq.vb_lock); 814 964 } 815 965 816 966 /* ··· 812 978 * The sink pad setting can only be cleared when all device nodes 813 979 * get released. 814 980 */ 815 - if (!isp->sw_contex.file_input && asd->fmt_auto->val) { 981 + if (asd->fmt_auto->val) { 816 982 struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; 817 983 818 984 atomisp_subdev_set_ffmt(&asd->subdev, fh.state, 819 985 V4L2_SUBDEV_FORMAT_ACTIVE, 820 986 ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); 821 987 } 822 - subdev_uninit: 988 + 823 989 if (atomisp_subdev_users(asd)) 824 990 goto done; 825 - 826 - /* clear the sink pad for file input */ 827 - if (isp->sw_contex.file_input && asd->fmt_auto->val) { 828 - struct v4l2_mbus_framefmt isp_sink_fmt = { 0 }; 829 - 830 - atomisp_subdev_set_ffmt(&asd->subdev, fh.state, 831 - V4L2_SUBDEV_FORMAT_ACTIVE, 832 - ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt); 833 - } 834 991 835 992 atomisp_css_free_stat_buffers(asd); 836 993 atomisp_free_internal_buffers(asd); ··· 832 1007 833 1008 /* clear the asd field to show this camera is not used */ 834 1009 isp->inputs[asd->input_curr].asd = NULL; 1010 + spin_lock_irqsave(&isp->lock, flags); 835 1011 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 1012 + spin_unlock_irqrestore(&isp->lock, flags); 836 1013 837 1014 if (atomisp_dev_users(isp)) 838 1015 goto done; ··· 856 1029 dev_err(isp->dev, "Failed to power off device\n"); 857 1030 858 1031 done: 859 - if (!acc_node) { 860 - atomisp_subdev_set_selection(&asd->subdev, fh.state, 861 - V4L2_SUBDEV_FORMAT_ACTIVE, 862 - atomisp_subdev_source_pad(vdev), 863 - V4L2_SEL_TGT_COMPOSE, 0, 864 - &clear_compose); 865 - } 866 - rt_mutex_unlock(&isp->mutex); 867 - mutex_unlock(&isp->streamoff_mutex); 1032 + atomisp_subdev_set_selection(&asd->subdev, fh.state, 1033 + V4L2_SUBDEV_FORMAT_ACTIVE, 1034 + atomisp_subdev_source_pad(vdev), 1035 + V4L2_SEL_TGT_COMPOSE, 0, 1036 + &clear_compose); 1037 + mutex_unlock(&isp->mutex); 868 1038 869 1039 return v4l2_fh_release(file); 870 1040 } ··· 1018 1194 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) 1019 1195 return -EACCES; 1020 1196 1021 - rt_mutex_lock(&isp->mutex); 1197 + mutex_lock(&isp->mutex); 1022 1198 1023 1199 if (!(vma->vm_flags & VM_SHARED)) { 1024 1200 /* Map private buffer. ··· 1029 1205 */ 1030 1206 vma->vm_flags |= VM_SHARED; 1031 1207 ret = hmm_mmap(vma, vma->vm_pgoff << PAGE_SHIFT); 1032 - rt_mutex_unlock(&isp->mutex); 1208 + mutex_unlock(&isp->mutex); 1033 1209 return ret; 1034 1210 } 1035 1211 ··· 1072 1248 } 1073 1249 raw_virt_addr->data_bytes = origin_size; 1074 1250 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; 1075 - rt_mutex_unlock(&isp->mutex); 1251 + mutex_unlock(&isp->mutex); 1076 1252 return 0; 1077 1253 } 1078 1254 ··· 1084 1260 ret = -EINVAL; 1085 1261 goto error; 1086 1262 } 1087 - rt_mutex_unlock(&isp->mutex); 1263 + mutex_unlock(&isp->mutex); 1088 1264 1089 1265 return atomisp_videobuf_mmap_mapper(&pipe->capq, vma); 1090 1266 1091 1267 error: 1092 - rt_mutex_unlock(&isp->mutex); 1268 + mutex_unlock(&isp->mutex); 1093 1269 1094 1270 return ret; 1095 - } 1096 - 1097 - static int atomisp_file_mmap(struct file *file, struct vm_area_struct *vma) 1098 - { 1099 - struct video_device *vdev = video_devdata(file); 1100 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1101 - 1102 - return videobuf_mmap_mapper(&pipe->outq, vma); 1103 1271 } 1104 1272 1105 1273 static __poll_t atomisp_poll(struct file *file, ··· 1101 1285 struct atomisp_device *isp = video_get_drvdata(vdev); 1102 1286 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1103 1287 1104 - rt_mutex_lock(&isp->mutex); 1288 + mutex_lock(&isp->mutex); 1105 1289 if (pipe->capq.streaming != 1) { 1106 - rt_mutex_unlock(&isp->mutex); 1290 + mutex_unlock(&isp->mutex); 1107 1291 return EPOLLERR; 1108 1292 } 1109 - rt_mutex_unlock(&isp->mutex); 1293 + mutex_unlock(&isp->mutex); 1110 1294 1111 1295 return videobuf_poll_stream(file, &pipe->capq, pt); 1112 1296 } ··· 1123 1307 * needs to be made safe for compat tasks instead. 1124 1308 .compat_ioctl32 = atomisp_compat_ioctl32, 1125 1309 */ 1126 - #endif 1127 - .poll = atomisp_poll, 1128 - }; 1129 - 1130 - const struct v4l2_file_operations atomisp_file_fops = { 1131 - .owner = THIS_MODULE, 1132 - .open = atomisp_open, 1133 - .release = atomisp_release, 1134 - .mmap = atomisp_file_mmap, 1135 - .unlocked_ioctl = video_ioctl2, 1136 - #ifdef CONFIG_COMPAT 1137 - /* .compat_ioctl32 = atomisp_compat_ioctl32, */ 1138 1310 #endif 1139 1311 .poll = atomisp_poll, 1140 1312 };
+40 -54
drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c
··· 134 134 135 135 static struct gmin_subdev *find_gmin_subdev(struct v4l2_subdev *subdev); 136 136 137 - /* 138 - * Legacy/stub behavior copied from upstream platform_camera.c. The 139 - * atomisp driver relies on these values being non-NULL in a few 140 - * places, even though they are hard-coded in all current 141 - * implementations. 142 - */ 143 - const struct atomisp_camera_caps *atomisp_get_default_camera_caps(void) 144 - { 145 - static const struct atomisp_camera_caps caps = { 146 - .sensor_num = 1, 147 - .sensor = { 148 - { .stream_num = 1, }, 149 - }, 150 - }; 151 - return &caps; 152 - } 153 - EXPORT_SYMBOL_GPL(atomisp_get_default_camera_caps); 154 - 155 137 const struct atomisp_platform_data *atomisp_get_platform_data(void) 156 138 { 157 139 return &pdata; ··· 1048 1066 return ret; 1049 1067 } 1050 1068 1069 + static int camera_sensor_csi_alloc(struct v4l2_subdev *sd, u32 port, u32 lanes, 1070 + u32 format, u32 bayer_order) 1071 + { 1072 + struct i2c_client *client = v4l2_get_subdevdata(sd); 1073 + struct camera_mipi_info *csi; 1074 + 1075 + csi = kzalloc(sizeof(*csi), GFP_KERNEL); 1076 + if (!csi) 1077 + return -ENOMEM; 1078 + 1079 + csi->port = port; 1080 + csi->num_lanes = lanes; 1081 + csi->input_format = format; 1082 + csi->raw_bayer_order = bayer_order; 1083 + v4l2_set_subdev_hostdata(sd, csi); 1084 + csi->metadata_format = ATOMISP_INPUT_FORMAT_EMBEDDED; 1085 + csi->metadata_effective_width = NULL; 1086 + dev_info(&client->dev, 1087 + "camera pdata: port: %d lanes: %d order: %8.8x\n", 1088 + port, lanes, bayer_order); 1089 + 1090 + return 0; 1091 + } 1092 + 1093 + static void camera_sensor_csi_free(struct v4l2_subdev *sd) 1094 + { 1095 + struct camera_mipi_info *csi; 1096 + 1097 + csi = v4l2_get_subdev_hostdata(sd); 1098 + kfree(csi); 1099 + } 1100 + 1051 1101 static int gmin_csi_cfg(struct v4l2_subdev *sd, int flag) 1052 1102 { 1053 1103 struct i2c_client *client = v4l2_get_subdevdata(sd); ··· 1088 1074 if (!client || !gs) 1089 1075 return -ENODEV; 1090 1076 1091 - return camera_sensor_csi(sd, gs->csi_port, gs->csi_lanes, 1092 - gs->csi_fmt, gs->csi_bayer, flag); 1077 + if (flag) 1078 + return camera_sensor_csi_alloc(sd, gs->csi_port, gs->csi_lanes, 1079 + gs->csi_fmt, gs->csi_bayer); 1080 + camera_sensor_csi_free(sd); 1081 + return 0; 1093 1082 } 1094 1083 1095 1084 static struct camera_vcm_control *gmin_get_vcm_ctrl(struct v4l2_subdev *subdev, ··· 1224 1207 if (!strcmp(var, "CamClk")) 1225 1208 return -EINVAL; 1226 1209 1227 - obj = acpi_evaluate_dsm(handle, &atomisp_dsm_guid, 0, 0, NULL); 1210 + /* Return on unexpected object type */ 1211 + obj = acpi_evaluate_dsm_typed(handle, &atomisp_dsm_guid, 0, 0, NULL, 1212 + ACPI_TYPE_PACKAGE); 1228 1213 if (!obj) { 1229 1214 dev_info_once(dev, "Didn't find ACPI _DSM table.\n"); 1230 1215 return -EINVAL; 1231 1216 } 1232 - 1233 - /* Return on unexpected object type */ 1234 - if (obj->type != ACPI_TYPE_PACKAGE) 1235 - return -EINVAL; 1236 1217 1237 1218 #if 0 /* Just for debugging purposes */ 1238 1219 for (i = 0; i < obj->package.count; i++) { ··· 1374 1359 return ret ? def : result; 1375 1360 } 1376 1361 EXPORT_SYMBOL_GPL(gmin_get_var_int); 1377 - 1378 - int camera_sensor_csi(struct v4l2_subdev *sd, u32 port, 1379 - u32 lanes, u32 format, u32 bayer_order, int flag) 1380 - { 1381 - struct i2c_client *client = v4l2_get_subdevdata(sd); 1382 - struct camera_mipi_info *csi = NULL; 1383 - 1384 - if (flag) { 1385 - csi = kzalloc(sizeof(*csi), GFP_KERNEL); 1386 - if (!csi) 1387 - return -ENOMEM; 1388 - csi->port = port; 1389 - csi->num_lanes = lanes; 1390 - csi->input_format = format; 1391 - csi->raw_bayer_order = bayer_order; 1392 - v4l2_set_subdev_hostdata(sd, (void *)csi); 1393 - csi->metadata_format = ATOMISP_INPUT_FORMAT_EMBEDDED; 1394 - csi->metadata_effective_width = NULL; 1395 - dev_info(&client->dev, 1396 - "camera pdata: port: %d lanes: %d order: %8.8x\n", 1397 - port, lanes, bayer_order); 1398 - } else { 1399 - csi = v4l2_get_subdev_hostdata(sd); 1400 - kfree(csi); 1401 - } 1402 - 1403 - return 0; 1404 - } 1405 - EXPORT_SYMBOL_GPL(camera_sensor_csi); 1406 1362 1407 1363 /* PCI quirk: The BYT ISP advertises PCI runtime PM but it doesn't 1408 1364 * work. Disable so the kernel framework doesn't hang the device
+5 -50
drivers/staging/media/atomisp/pci/atomisp_internal.h
··· 34 34 #include "sh_css_legacy.h" 35 35 36 36 #include "atomisp_csi2.h" 37 - #include "atomisp_file.h" 38 37 #include "atomisp_subdev.h" 39 38 #include "atomisp_tpg.h" 40 39 #include "atomisp_compat.h" ··· 85 86 #define ATOM_ISP_POWER_DOWN 0 86 87 #define ATOM_ISP_POWER_UP 1 87 88 88 - #define ATOM_ISP_MAX_INPUTS 4 89 + #define ATOM_ISP_MAX_INPUTS 3 89 90 90 91 #define ATOMISP_SC_TYPE_SIZE 2 91 92 92 93 #define ATOMISP_ISP_TIMEOUT_DURATION (2 * HZ) 93 94 #define ATOMISP_EXT_ISP_TIMEOUT_DURATION (6 * HZ) 94 - #define ATOMISP_ISP_FILE_TIMEOUT_DURATION (60 * HZ) 95 95 #define ATOMISP_WDT_KEEP_CURRENT_DELAY 0 96 96 #define ATOMISP_ISP_MAX_TIMEOUT_COUNT 2 97 97 #define ATOMISP_CSS_STOP_TIMEOUT_US 200000 ··· 104 106 #define ATOMISP_DELAYED_INIT_NOT_QUEUED 0 105 107 #define ATOMISP_DELAYED_INIT_QUEUED 1 106 108 #define ATOMISP_DELAYED_INIT_DONE 2 107 - 108 - #define ATOMISP_CALC_CSS_PREV_OVERLAP(lines) \ 109 - ((lines) * 38 / 100 & 0xfffffe) 110 109 111 110 /* 112 111 * Define how fast CPU should be able to serve ISP interrupts. ··· 127 132 * Moorefield/Baytrail platform. 128 133 */ 129 134 #define ATOMISP_SOC_CAMERA(asd) \ 130 - (asd->isp->inputs[asd->input_curr].type == SOC_CAMERA \ 131 - && asd->isp->inputs[asd->input_curr].camera_caps-> \ 132 - sensor[asd->sensor_curr].stream_num == 1) 135 + (asd->isp->inputs[asd->input_curr].type == SOC_CAMERA) 133 136 134 137 #define ATOMISP_USE_YUVPP(asd) \ 135 138 (ATOMISP_SOC_CAMERA(asd) && ATOMISP_CSS_SUPPORT_YUVPP && \ ··· 160 167 */ 161 168 struct atomisp_sub_device *asd; 162 169 163 - const struct atomisp_camera_caps *camera_caps; 164 170 int sensor_index; 165 171 }; 166 172 ··· 195 203 }; 196 204 197 205 struct atomisp_sw_contex { 198 - bool file_input; 199 206 int power_state; 200 207 int running_freq; 201 208 }; ··· 232 241 233 242 struct atomisp_mipi_csi2_device csi2_port[ATOMISP_CAMERA_NR_PORTS]; 234 243 struct atomisp_tpg_device tpg; 235 - struct atomisp_file_device file_dev; 236 244 237 245 /* Purpose of mutex is to protect and serialize use of isp data 238 246 * structures and css API calls. */ 239 - struct rt_mutex mutex; 240 - /* 241 - * This mutex ensures that we don't allow an open to succeed while 242 - * the initialization process is incomplete 243 - */ 244 - struct rt_mutex loading; 245 - /* Set once the ISP is ready to allow opens */ 246 - bool ready; 247 - /* 248 - * Serialise streamoff: mutex is dropped during streamoff to 249 - * cancel the watchdog queue. MUST be acquired BEFORE 250 - * "mutex". 251 - */ 252 - struct mutex streamoff_mutex; 247 + struct mutex mutex; 253 248 254 249 unsigned int input_cnt; 255 250 struct atomisp_input_subdev inputs[ATOM_ISP_MAX_INPUTS]; ··· 249 272 /* isp timeout status flag */ 250 273 bool isp_timeout; 251 274 bool isp_fatal_error; 252 - struct workqueue_struct *wdt_work_queue; 253 - struct work_struct wdt_work; 275 + struct work_struct assert_recovery_work; 254 276 255 - /* ISP2400 */ 256 - atomic_t wdt_count; 257 - 258 - atomic_t wdt_work_queued; 259 - 260 - spinlock_t lock; /* Just for streaming below */ 277 + spinlock_t lock; /* Protects asd[i].streaming */ 261 278 262 279 bool need_gfx_throttle; 263 280 ··· 266 295 container_of(dev, struct atomisp_device, v4l2_dev) 267 296 268 297 extern struct device *atomisp_dev; 269 - 270 - #define atomisp_is_wdt_running(a) timer_pending(&(a)->wdt) 271 - 272 - /* ISP2401 */ 273 - void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe, 274 - unsigned int delay); 275 - void atomisp_wdt_refresh(struct atomisp_sub_device *asd, unsigned int delay); 276 - 277 - /* ISP2400 */ 278 - void atomisp_wdt_start(struct atomisp_sub_device *asd); 279 - 280 - /* ISP2401 */ 281 - void atomisp_wdt_start_pipe(struct atomisp_video_pipe *pipe); 282 - void atomisp_wdt_stop_pipe(struct atomisp_video_pipe *pipe, bool sync); 283 - 284 - void atomisp_wdt_stop(struct atomisp_sub_device *asd, bool sync); 285 298 286 299 #endif /* __ATOMISP_INTERNAL_H__ */
+142 -634
drivers/staging/media/atomisp/pci/atomisp_ioctl.c
··· 535 535 return NULL; 536 536 } 537 537 538 + int atomisp_pipe_check(struct atomisp_video_pipe *pipe, bool settings_change) 539 + { 540 + lockdep_assert_held(&pipe->isp->mutex); 541 + 542 + if (pipe->isp->isp_fatal_error) 543 + return -EIO; 544 + 545 + switch (pipe->asd->streaming) { 546 + case ATOMISP_DEVICE_STREAMING_DISABLED: 547 + break; 548 + case ATOMISP_DEVICE_STREAMING_ENABLED: 549 + if (settings_change) { 550 + dev_err(pipe->isp->dev, "Set fmt/input IOCTL while streaming\n"); 551 + return -EBUSY; 552 + } 553 + break; 554 + case ATOMISP_DEVICE_STREAMING_STOPPING: 555 + dev_err(pipe->isp->dev, "IOCTL issued while stopping\n"); 556 + return -EBUSY; 557 + default: 558 + return -EINVAL; 559 + } 560 + 561 + return 0; 562 + } 563 + 538 564 /* 539 565 * v4l2 ioctls 540 566 * return ISP capabilities ··· 635 609 return asd->video_out_preview.capq.streaming 636 610 + asd->video_out_capture.capq.streaming 637 611 + asd->video_out_video_capture.capq.streaming 638 - + asd->video_out_vf.capq.streaming 639 - + asd->video_in.capq.streaming; 612 + + asd->video_out_vf.capq.streaming; 640 613 } 641 614 642 615 unsigned int atomisp_streaming_count(struct atomisp_device *isp) ··· 655 630 static int atomisp_g_input(struct file *file, void *fh, unsigned int *input) 656 631 { 657 632 struct video_device *vdev = video_devdata(file); 658 - struct atomisp_device *isp = video_get_drvdata(vdev); 659 633 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 660 634 661 - if (!asd) { 662 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 663 - __func__, vdev->name); 664 - return -EINVAL; 665 - } 666 - 667 - rt_mutex_lock(&isp->mutex); 668 635 *input = asd->input_curr; 669 - rt_mutex_unlock(&isp->mutex); 670 - 671 636 return 0; 672 637 } 673 638 ··· 668 653 { 669 654 struct video_device *vdev = video_devdata(file); 670 655 struct atomisp_device *isp = video_get_drvdata(vdev); 671 - struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 656 + struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 657 + struct atomisp_sub_device *asd = pipe->asd; 672 658 struct v4l2_subdev *camera = NULL; 673 659 struct v4l2_subdev *motor; 674 660 int ret; 675 661 676 - if (!asd) { 677 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 678 - __func__, vdev->name); 679 - return -EINVAL; 680 - } 662 + ret = atomisp_pipe_check(pipe, true); 663 + if (ret) 664 + return ret; 681 665 682 - rt_mutex_lock(&isp->mutex); 683 666 if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) { 684 667 dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt); 685 - ret = -EINVAL; 686 - goto error; 668 + return -EINVAL; 687 669 } 688 670 689 671 /* ··· 692 680 dev_err(isp->dev, 693 681 "%s, camera is already used by stream: %d\n", __func__, 694 682 isp->inputs[input].asd->index); 695 - ret = -EBUSY; 696 - goto error; 683 + return -EBUSY; 697 684 } 698 685 699 686 camera = isp->inputs[input].camera; 700 687 if (!camera) { 701 688 dev_err(isp->dev, "%s, no camera\n", __func__); 702 - ret = -EINVAL; 703 - goto error; 704 - } 705 - 706 - if (atomisp_subdev_streaming_count(asd)) { 707 - dev_err(isp->dev, 708 - "ISP is still streaming, stop first\n"); 709 - ret = -EINVAL; 710 - goto error; 689 + return -EINVAL; 711 690 } 712 691 713 692 /* power off the current owned sensor, as it is not used this time */ ··· 717 714 ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1); 718 715 if (ret) { 719 716 dev_err(isp->dev, "Failed to power-on sensor\n"); 720 - goto error; 717 + return ret; 721 718 } 722 719 /* 723 720 * Some sensor driver resets the run mode during power-on, thus force ··· 730 727 0, isp->inputs[input].sensor_index, 0); 731 728 if (ret && (ret != -ENOIOCTLCMD)) { 732 729 dev_err(isp->dev, "Failed to select sensor\n"); 733 - goto error; 730 + return ret; 734 731 } 735 732 736 733 if (!IS_ISP2401) { ··· 741 738 ret = v4l2_subdev_call(motor, core, s_power, 1); 742 739 } 743 740 744 - if (!isp->sw_contex.file_input && motor) 741 + if (motor) 745 742 ret = v4l2_subdev_call(motor, core, init, 1); 746 743 747 744 asd->input_curr = input; 748 745 /* mark this camera is used by the current stream */ 749 746 isp->inputs[input].asd = asd; 750 - rt_mutex_unlock(&isp->mutex); 751 747 752 748 return 0; 753 - 754 - error: 755 - rt_mutex_unlock(&isp->mutex); 756 - 757 - return ret; 758 749 } 759 750 760 751 static int atomisp_enum_framesizes(struct file *file, void *priv, ··· 816 819 unsigned int i, fi = 0; 817 820 int rval; 818 821 819 - if (!asd) { 820 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 821 - __func__, vdev->name); 822 - return -EINVAL; 823 - } 824 - 825 822 camera = isp->inputs[asd->input_curr].camera; 826 823 if(!camera) { 827 824 dev_err(isp->dev, "%s(): camera is NULL, device is %s\n", ··· 823 832 return -EINVAL; 824 833 } 825 834 826 - rt_mutex_lock(&isp->mutex); 827 - 828 835 rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code); 829 836 if (rval == -ENOIOCTLCMD) { 830 837 dev_warn(isp->dev, 831 838 "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n", 832 839 camera->name); 833 840 } 834 - rt_mutex_unlock(&isp->mutex); 835 841 836 842 if (rval) 837 843 return rval; ··· 858 870 } 859 871 860 872 return -EINVAL; 861 - } 862 - 863 - static int atomisp_g_fmt_file(struct file *file, void *fh, 864 - struct v4l2_format *f) 865 - { 866 - struct video_device *vdev = video_devdata(file); 867 - struct atomisp_device *isp = video_get_drvdata(vdev); 868 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 869 - 870 - rt_mutex_lock(&isp->mutex); 871 - f->fmt.pix = pipe->pix; 872 - rt_mutex_unlock(&isp->mutex); 873 - 874 - return 0; 875 873 } 876 874 877 875 static int atomisp_adjust_fmt(struct v4l2_format *f) ··· 931 957 struct v4l2_format *f) 932 958 { 933 959 struct video_device *vdev = video_devdata(file); 934 - struct atomisp_device *isp = video_get_drvdata(vdev); 935 960 int ret; 936 961 937 - rt_mutex_lock(&isp->mutex); 938 - ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL); 939 - rt_mutex_unlock(&isp->mutex); 962 + /* 963 + * atomisp_try_fmt() gived results with padding included, note 964 + * (this gets removed again by the atomisp_adjust_fmt() call below. 965 + */ 966 + f->fmt.pix.width += pad_w; 967 + f->fmt.pix.height += pad_h; 940 968 969 + ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL); 941 970 if (ret) 942 971 return ret; 943 972 ··· 951 974 struct v4l2_format *f) 952 975 { 953 976 struct video_device *vdev = video_devdata(file); 954 - struct atomisp_device *isp = video_get_drvdata(vdev); 955 977 struct atomisp_video_pipe *pipe; 956 978 957 - rt_mutex_lock(&isp->mutex); 958 979 pipe = atomisp_to_video_pipe(vdev); 959 - rt_mutex_unlock(&isp->mutex); 960 980 961 981 f->fmt.pix = pipe->pix; 962 982 ··· 966 992 f->fmt.pix.height = 10000; 967 993 968 994 return atomisp_try_fmt_cap(file, fh, f); 969 - } 970 - 971 - static int atomisp_s_fmt_cap(struct file *file, void *fh, 972 - struct v4l2_format *f) 973 - { 974 - struct video_device *vdev = video_devdata(file); 975 - struct atomisp_device *isp = video_get_drvdata(vdev); 976 - int ret; 977 - 978 - rt_mutex_lock(&isp->mutex); 979 - if (isp->isp_fatal_error) { 980 - ret = -EIO; 981 - rt_mutex_unlock(&isp->mutex); 982 - return ret; 983 - } 984 - ret = atomisp_set_fmt(vdev, f); 985 - rt_mutex_unlock(&isp->mutex); 986 - return ret; 987 - } 988 - 989 - static int atomisp_s_fmt_file(struct file *file, void *fh, 990 - struct v4l2_format *f) 991 - { 992 - struct video_device *vdev = video_devdata(file); 993 - struct atomisp_device *isp = video_get_drvdata(vdev); 994 - int ret; 995 - 996 - rt_mutex_lock(&isp->mutex); 997 - ret = atomisp_set_fmt_file(vdev, f); 998 - rt_mutex_unlock(&isp->mutex); 999 - return ret; 1000 995 } 1001 996 1002 997 /* ··· 1103 1160 /* 1104 1161 * Initiate Memory Mapping or User Pointer I/O 1105 1162 */ 1106 - int __atomisp_reqbufs(struct file *file, void *fh, 1107 - struct v4l2_requestbuffers *req) 1163 + int atomisp_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req) 1108 1164 { 1109 1165 struct video_device *vdev = video_devdata(file); 1110 1166 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); ··· 1112 1170 struct ia_css_frame *frame; 1113 1171 struct videobuf_vmalloc_memory *vm_mem; 1114 1172 u16 source_pad = atomisp_subdev_source_pad(vdev); 1115 - u16 stream_id; 1116 1173 int ret = 0, i = 0; 1117 - 1118 - if (!asd) { 1119 - dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", 1120 - __func__, vdev->name); 1121 - return -EINVAL; 1122 - } 1123 - stream_id = atomisp_source_pad_to_stream_id(asd, source_pad); 1124 1174 1125 1175 if (req->count == 0) { 1126 1176 mutex_lock(&pipe->capq.vb_lock); ··· 1134 1200 if (ret) 1135 1201 return ret; 1136 1202 1137 - atomisp_alloc_css_stat_bufs(asd, stream_id); 1203 + atomisp_alloc_css_stat_bufs(asd, ATOMISP_INPUT_STREAM_GENERAL); 1138 1204 1139 1205 /* 1140 1206 * for user pointer type, buffers are not really allocated here, ··· 1172 1238 return -ENOMEM; 1173 1239 } 1174 1240 1175 - int atomisp_reqbufs(struct file *file, void *fh, 1176 - struct v4l2_requestbuffers *req) 1177 - { 1178 - struct video_device *vdev = video_devdata(file); 1179 - struct atomisp_device *isp = video_get_drvdata(vdev); 1180 - int ret; 1181 - 1182 - rt_mutex_lock(&isp->mutex); 1183 - ret = __atomisp_reqbufs(file, fh, req); 1184 - rt_mutex_unlock(&isp->mutex); 1185 - 1186 - return ret; 1187 - } 1188 - 1189 - static int atomisp_reqbufs_file(struct file *file, void *fh, 1190 - struct v4l2_requestbuffers *req) 1191 - { 1192 - struct video_device *vdev = video_devdata(file); 1193 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1194 - 1195 - if (req->count == 0) { 1196 - mutex_lock(&pipe->outq.vb_lock); 1197 - atomisp_videobuf_free_queue(&pipe->outq); 1198 - mutex_unlock(&pipe->outq.vb_lock); 1199 - return 0; 1200 - } 1201 - 1202 - return videobuf_reqbufs(&pipe->outq, req); 1203 - } 1204 - 1205 1241 /* application query the status of a buffer */ 1206 1242 static int atomisp_querybuf(struct file *file, void *fh, 1207 1243 struct v4l2_buffer *buf) ··· 1180 1276 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1181 1277 1182 1278 return videobuf_querybuf(&pipe->capq, buf); 1183 - } 1184 - 1185 - static int atomisp_querybuf_file(struct file *file, void *fh, 1186 - struct v4l2_buffer *buf) 1187 - { 1188 - struct video_device *vdev = video_devdata(file); 1189 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1190 - 1191 - return videobuf_querybuf(&pipe->outq, buf); 1192 1279 } 1193 1280 1194 1281 /* ··· 1200 1305 struct ia_css_frame *handle = NULL; 1201 1306 u32 length; 1202 1307 u32 pgnr; 1203 - int ret = 0; 1308 + int ret; 1204 1309 1205 - if (!asd) { 1206 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 1207 - __func__, vdev->name); 1208 - return -EINVAL; 1209 - } 1210 - 1211 - rt_mutex_lock(&isp->mutex); 1212 - if (isp->isp_fatal_error) { 1213 - ret = -EIO; 1214 - goto error; 1215 - } 1216 - 1217 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) { 1218 - dev_err(isp->dev, "%s: reject, as ISP at stopping.\n", 1219 - __func__); 1220 - ret = -EIO; 1221 - goto error; 1222 - } 1310 + ret = atomisp_pipe_check(pipe, false); 1311 + if (ret) 1312 + return ret; 1223 1313 1224 1314 if (!buf || buf->index >= VIDEO_MAX_FRAME || 1225 1315 !pipe->capq.bufs[buf->index]) { 1226 1316 dev_err(isp->dev, "Invalid index for qbuf.\n"); 1227 - ret = -EINVAL; 1228 - goto error; 1317 + return -EINVAL; 1229 1318 } 1230 1319 1231 1320 /* ··· 1217 1338 * address and reprograme out page table properly 1218 1339 */ 1219 1340 if (buf->memory == V4L2_MEMORY_USERPTR) { 1341 + if (offset_in_page(buf->m.userptr)) { 1342 + dev_err(isp->dev, "Error userptr is not page aligned.\n"); 1343 + return -EINVAL; 1344 + } 1345 + 1220 1346 vb = pipe->capq.bufs[buf->index]; 1221 1347 vm_mem = vb->priv; 1222 - if (!vm_mem) { 1223 - ret = -EINVAL; 1224 - goto error; 1225 - } 1348 + if (!vm_mem) 1349 + return -EINVAL; 1226 1350 1227 1351 length = vb->bsize; 1228 1352 pgnr = (length + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ··· 1234 1352 goto done; 1235 1353 1236 1354 if (atomisp_get_css_frame_info(asd, 1237 - atomisp_subdev_source_pad(vdev), &frame_info)) { 1238 - ret = -EIO; 1239 - goto error; 1240 - } 1355 + atomisp_subdev_source_pad(vdev), &frame_info)) 1356 + return -EIO; 1241 1357 1242 1358 ret = ia_css_frame_map(&handle, &frame_info, 1243 1359 (void __user *)buf->m.userptr, 1244 1360 pgnr); 1245 1361 if (ret) { 1246 1362 dev_err(isp->dev, "Failed to map user buffer\n"); 1247 - goto error; 1363 + return ret; 1248 1364 } 1249 1365 1250 1366 if (vm_mem->vaddr) { ··· 1286 1406 1287 1407 pipe->frame_params[buf->index] = NULL; 1288 1408 1289 - rt_mutex_unlock(&isp->mutex); 1290 - 1409 + mutex_unlock(&isp->mutex); 1291 1410 ret = videobuf_qbuf(&pipe->capq, buf); 1292 - rt_mutex_lock(&isp->mutex); 1411 + mutex_lock(&isp->mutex); 1293 1412 if (ret) 1294 - goto error; 1413 + return ret; 1295 1414 1296 1415 /* TODO: do this better, not best way to queue to css */ 1297 1416 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { ··· 1298 1419 atomisp_handle_parameter_and_buffer(pipe); 1299 1420 } else { 1300 1421 atomisp_qbuffers_to_css(asd); 1301 - 1302 - if (!IS_ISP2401) { 1303 - if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd)) 1304 - atomisp_wdt_start(asd); 1305 - } else { 1306 - if (!atomisp_is_wdt_running(pipe) && 1307 - atomisp_buffers_queued_pipe(pipe)) 1308 - atomisp_wdt_start_pipe(pipe); 1309 - } 1310 1422 } 1311 1423 } 1312 1424 ··· 1319 1449 asd->pending_capture_request++; 1320 1450 dev_dbg(isp->dev, "Add one pending capture request.\n"); 1321 1451 } 1322 - rt_mutex_unlock(&isp->mutex); 1323 1452 1324 1453 dev_dbg(isp->dev, "qbuf buffer %d (%s) for asd%d\n", buf->index, 1325 1454 vdev->name, asd->index); 1326 1455 1327 - return ret; 1328 - 1329 - error: 1330 - rt_mutex_unlock(&isp->mutex); 1331 - return ret; 1332 - } 1333 - 1334 - static int atomisp_qbuf_file(struct file *file, void *fh, 1335 - struct v4l2_buffer *buf) 1336 - { 1337 - struct video_device *vdev = video_devdata(file); 1338 - struct atomisp_device *isp = video_get_drvdata(vdev); 1339 - struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1340 - int ret; 1341 - 1342 - rt_mutex_lock(&isp->mutex); 1343 - if (isp->isp_fatal_error) { 1344 - ret = -EIO; 1345 - goto error; 1346 - } 1347 - 1348 - if (!buf || buf->index >= VIDEO_MAX_FRAME || 1349 - !pipe->outq.bufs[buf->index]) { 1350 - dev_err(isp->dev, "Invalid index for qbuf.\n"); 1351 - ret = -EINVAL; 1352 - goto error; 1353 - } 1354 - 1355 - if (buf->memory != V4L2_MEMORY_MMAP) { 1356 - dev_err(isp->dev, "Unsupported memory method\n"); 1357 - ret = -EINVAL; 1358 - goto error; 1359 - } 1360 - 1361 - if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1362 - dev_err(isp->dev, "Unsupported buffer type\n"); 1363 - ret = -EINVAL; 1364 - goto error; 1365 - } 1366 - rt_mutex_unlock(&isp->mutex); 1367 - 1368 - return videobuf_qbuf(&pipe->outq, buf); 1369 - 1370 - error: 1371 - rt_mutex_unlock(&isp->mutex); 1372 - 1373 - return ret; 1456 + return 0; 1374 1457 } 1375 1458 1376 1459 static int __get_frame_exp_id(struct atomisp_video_pipe *pipe, ··· 1352 1529 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1353 1530 struct atomisp_sub_device *asd = pipe->asd; 1354 1531 struct atomisp_device *isp = video_get_drvdata(vdev); 1355 - int ret = 0; 1532 + int ret; 1356 1533 1357 - if (!asd) { 1358 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 1359 - __func__, vdev->name); 1360 - return -EINVAL; 1361 - } 1534 + ret = atomisp_pipe_check(pipe, false); 1535 + if (ret) 1536 + return ret; 1362 1537 1363 - rt_mutex_lock(&isp->mutex); 1364 - 1365 - if (isp->isp_fatal_error) { 1366 - rt_mutex_unlock(&isp->mutex); 1367 - return -EIO; 1368 - } 1369 - 1370 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) { 1371 - rt_mutex_unlock(&isp->mutex); 1372 - dev_err(isp->dev, "%s: reject, as ISP at stopping.\n", 1373 - __func__); 1374 - return -EIO; 1375 - } 1376 - 1377 - rt_mutex_unlock(&isp->mutex); 1378 - 1538 + mutex_unlock(&isp->mutex); 1379 1539 ret = videobuf_dqbuf(&pipe->capq, buf, file->f_flags & O_NONBLOCK); 1540 + mutex_lock(&isp->mutex); 1380 1541 if (ret) { 1381 1542 if (ret != -EAGAIN) 1382 1543 dev_dbg(isp->dev, "<%s: %d\n", __func__, ret); 1383 1544 return ret; 1384 1545 } 1385 - rt_mutex_lock(&isp->mutex); 1546 + 1386 1547 buf->bytesused = pipe->pix.sizeimage; 1387 1548 buf->reserved = asd->frame_status[buf->index]; 1388 1549 ··· 1380 1573 if (!(buf->flags & V4L2_BUF_FLAG_ERROR)) 1381 1574 buf->reserved |= __get_frame_exp_id(pipe, buf) << 16; 1382 1575 buf->reserved2 = pipe->frame_config_id[buf->index]; 1383 - rt_mutex_unlock(&isp->mutex); 1384 1576 1385 1577 dev_dbg(isp->dev, 1386 1578 "dqbuf buffer %d (%s) for asd%d with exp_id %d, isp_config_id %d\n", ··· 1428 1622 1429 1623 static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd) 1430 1624 { 1431 - struct atomisp_device *isp = asd->isp; 1432 - 1433 - if (isp->inputs[asd->input_curr].camera_caps-> 1434 - sensor[asd->sensor_curr].stream_num > 1) { 1435 - if (asd->high_speed_mode) 1436 - return 1; 1437 - else 1438 - return 2; 1439 - } 1440 - 1441 1625 if (asd->vfpp->val != ATOMISP_VFPP_ENABLE || 1442 1626 asd->copy_mode) 1443 1627 return 1; ··· 1446 1650 int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp, 1447 1651 bool isp_timeout) 1448 1652 { 1449 - unsigned int master = -1, slave = -1, delay_slave = 0; 1450 - int i, ret; 1653 + unsigned int master, slave, delay_slave = 0; 1654 + int ret; 1451 1655 1452 - /* 1453 - * ISP only support 2 streams now so ignore multiple master/slave 1454 - * case to reduce the delay between 2 stream_on calls. 1455 - */ 1456 - for (i = 0; i < isp->num_of_streams; i++) { 1457 - int sensor_index = isp->asd[i].input_curr; 1458 - 1459 - if (isp->inputs[sensor_index].camera_caps-> 1460 - sensor[isp->asd[i].sensor_curr].is_slave) 1461 - slave = sensor_index; 1462 - else 1463 - master = sensor_index; 1464 - } 1465 - 1466 - if (master == -1 || slave == -1) { 1467 - master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR; 1468 - slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR; 1469 - dev_warn(isp->dev, 1470 - "depth mode use default master=%s.slave=%s.\n", 1471 - isp->inputs[master].camera->name, 1472 - isp->inputs[slave].camera->name); 1473 - } 1656 + master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR; 1657 + slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR; 1658 + dev_warn(isp->dev, 1659 + "depth mode use default master=%s.slave=%s.\n", 1660 + isp->inputs[master].camera->name, 1661 + isp->inputs[slave].camera->name); 1474 1662 1475 1663 ret = v4l2_subdev_call(isp->inputs[master].camera, core, 1476 1664 ioctl, ATOMISP_IOC_G_DEPTH_SYNC_COMP, ··· 1488 1708 return 0; 1489 1709 } 1490 1710 1491 - /* FIXME! ISP2400 */ 1492 - static void __wdt_on_master_slave_sensor(struct atomisp_device *isp, 1493 - unsigned int wdt_duration) 1494 - { 1495 - if (atomisp_buffers_queued(&isp->asd[0])) 1496 - atomisp_wdt_refresh(&isp->asd[0], wdt_duration); 1497 - if (atomisp_buffers_queued(&isp->asd[1])) 1498 - atomisp_wdt_refresh(&isp->asd[1], wdt_duration); 1499 - } 1500 - 1501 - /* FIXME! ISP2401 */ 1502 - static void __wdt_on_master_slave_sensor_pipe(struct atomisp_video_pipe *pipe, 1503 - unsigned int wdt_duration, 1504 - bool enable) 1505 - { 1506 - static struct atomisp_video_pipe *pipe0; 1507 - 1508 - if (enable) { 1509 - if (atomisp_buffers_queued_pipe(pipe0)) 1510 - atomisp_wdt_refresh_pipe(pipe0, wdt_duration); 1511 - if (atomisp_buffers_queued_pipe(pipe)) 1512 - atomisp_wdt_refresh_pipe(pipe, wdt_duration); 1513 - } else { 1514 - pipe0 = pipe; 1515 - } 1516 - } 1517 - 1518 - static void atomisp_pause_buffer_event(struct atomisp_device *isp) 1519 - { 1520 - struct v4l2_event event = {0}; 1521 - int i; 1522 - 1523 - event.type = V4L2_EVENT_ATOMISP_PAUSE_BUFFER; 1524 - 1525 - for (i = 0; i < isp->num_of_streams; i++) { 1526 - int sensor_index = isp->asd[i].input_curr; 1527 - 1528 - if (isp->inputs[sensor_index].camera_caps-> 1529 - sensor[isp->asd[i].sensor_curr].is_slave) { 1530 - v4l2_event_queue(isp->asd[i].subdev.devnode, &event); 1531 - break; 1532 - } 1533 - } 1534 - } 1535 - 1536 1711 /* Input system HW workaround */ 1537 1712 /* Input system address translation corrupts burst during */ 1538 1713 /* invalidate. SW workaround for this is to set burst length */ ··· 1519 1784 struct pci_dev *pdev = to_pci_dev(isp->dev); 1520 1785 enum ia_css_pipe_id css_pipe_id; 1521 1786 unsigned int sensor_start_stream; 1522 - unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION; 1523 - int ret = 0; 1524 1787 unsigned long irqflags; 1525 - 1526 - if (!asd) { 1527 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 1528 - __func__, vdev->name); 1529 - return -EINVAL; 1530 - } 1788 + int ret; 1531 1789 1532 1790 dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n", 1533 1791 atomisp_subdev_source_pad(vdev), asd->index); ··· 1530 1802 return -EINVAL; 1531 1803 } 1532 1804 1533 - rt_mutex_lock(&isp->mutex); 1534 - if (isp->isp_fatal_error) { 1535 - ret = -EIO; 1536 - goto out; 1537 - } 1538 - 1539 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) { 1540 - ret = -EBUSY; 1541 - goto out; 1542 - } 1805 + ret = atomisp_pipe_check(pipe, false); 1806 + if (ret) 1807 + return ret; 1543 1808 1544 1809 if (pipe->capq.streaming) 1545 - goto out; 1810 + return 0; 1546 1811 1547 1812 /* Input system HW workaround */ 1548 1813 atomisp_dma_burst_len_cfg(asd); ··· 1550 1829 if (list_empty(&pipe->capq.stream)) { 1551 1830 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 1552 1831 dev_dbg(isp->dev, "no buffer in the queue\n"); 1553 - ret = -EINVAL; 1554 - goto out; 1832 + return -EINVAL; 1555 1833 } 1556 1834 spin_unlock_irqrestore(&pipe->irq_lock, irqflags); 1557 1835 1558 1836 ret = videobuf_streamon(&pipe->capq); 1559 1837 if (ret) 1560 - goto out; 1838 + return ret; 1561 1839 1562 1840 /* Reset pending capture request count. */ 1563 1841 asd->pending_capture_request = 0; 1564 1842 1565 - if ((atomisp_subdev_streaming_count(asd) > sensor_start_stream) && 1566 - (!isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl)) { 1843 + if (atomisp_subdev_streaming_count(asd) > sensor_start_stream) { 1567 1844 /* trigger still capture */ 1568 1845 if (asd->continuous_mode->val && 1569 1846 atomisp_subdev_source_pad(vdev) ··· 1575 1856 1576 1857 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) { 1577 1858 flush_work(&asd->delayed_init_work); 1578 - rt_mutex_unlock(&isp->mutex); 1579 - if (wait_for_completion_interruptible( 1580 - &asd->init_done) != 0) 1859 + mutex_unlock(&isp->mutex); 1860 + ret = wait_for_completion_interruptible(&asd->init_done); 1861 + mutex_lock(&isp->mutex); 1862 + if (ret != 0) 1581 1863 return -ERESTARTSYS; 1582 - rt_mutex_lock(&isp->mutex); 1583 1864 } 1584 1865 1585 1866 /* handle per_frame_setting parameter and buffers */ ··· 1601 1882 asd->params.offline_parm.num_captures, 1602 1883 asd->params.offline_parm.skip_frames, 1603 1884 asd->params.offline_parm.offset); 1604 - if (ret) { 1605 - ret = -EINVAL; 1606 - goto out; 1607 - } 1608 - if (asd->depth_mode->val) 1609 - atomisp_pause_buffer_event(isp); 1885 + if (ret) 1886 + return -EINVAL; 1610 1887 } 1611 1888 } 1612 1889 atomisp_qbuffers_to_css(asd); 1613 - goto out; 1890 + return 0; 1614 1891 } 1615 1892 1616 1893 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { ··· 1632 1917 1633 1918 ret = atomisp_css_start(asd, css_pipe_id, false); 1634 1919 if (ret) 1635 - goto out; 1920 + return ret; 1636 1921 1922 + spin_lock_irqsave(&isp->lock, irqflags); 1637 1923 asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED; 1924 + spin_unlock_irqrestore(&isp->lock, irqflags); 1638 1925 atomic_set(&asd->sof_count, -1); 1639 1926 atomic_set(&asd->sequence, -1); 1640 1927 atomic_set(&asd->sequence_temp, -1); 1641 - if (isp->sw_contex.file_input) 1642 - wdt_duration = ATOMISP_ISP_FILE_TIMEOUT_DURATION; 1643 1928 1644 1929 asd->params.dis_proj_data_valid = false; 1645 1930 asd->latest_preview_exp_id = 0; ··· 1653 1938 1654 1939 /* Only start sensor when the last streaming instance started */ 1655 1940 if (atomisp_subdev_streaming_count(asd) < sensor_start_stream) 1656 - goto out; 1941 + return 0; 1657 1942 1658 1943 start_sensor: 1659 1944 if (isp->flash) { ··· 1662 1947 atomisp_setup_flash(asd); 1663 1948 } 1664 1949 1665 - if (!isp->sw_contex.file_input) { 1666 - atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1667 - atomisp_css_valid_sof(isp)); 1668 - atomisp_csi2_configure(asd); 1669 - /* 1670 - * set freq to max when streaming count > 1 which indicate 1671 - * dual camera would run 1672 - */ 1673 - if (atomisp_streaming_count(isp) > 1) { 1674 - if (atomisp_freq_scaling(isp, 1675 - ATOMISP_DFS_MODE_MAX, false) < 0) 1676 - dev_dbg(isp->dev, "DFS max mode failed!\n"); 1677 - } else { 1678 - if (atomisp_freq_scaling(isp, 1679 - ATOMISP_DFS_MODE_AUTO, false) < 0) 1680 - dev_dbg(isp->dev, "DFS auto mode failed!\n"); 1681 - } 1682 - } else { 1683 - if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false) < 0) 1950 + atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1951 + atomisp_css_valid_sof(isp)); 1952 + atomisp_csi2_configure(asd); 1953 + /* 1954 + * set freq to max when streaming count > 1 which indicate 1955 + * dual camera would run 1956 + */ 1957 + if (atomisp_streaming_count(isp) > 1) { 1958 + if (atomisp_freq_scaling(isp, 1959 + ATOMISP_DFS_MODE_MAX, false) < 0) 1684 1960 dev_dbg(isp->dev, "DFS max mode failed!\n"); 1961 + } else { 1962 + if (atomisp_freq_scaling(isp, 1963 + ATOMISP_DFS_MODE_AUTO, false) < 0) 1964 + dev_dbg(isp->dev, "DFS auto mode failed!\n"); 1685 1965 } 1686 1966 1687 1967 if (asd->depth_mode->val && atomisp_streaming_count(isp) == ··· 1684 1974 ret = atomisp_stream_on_master_slave_sensor(isp, false); 1685 1975 if (ret) { 1686 1976 dev_err(isp->dev, "master slave sensor stream on failed!\n"); 1687 - goto out; 1977 + return ret; 1688 1978 } 1689 - if (!IS_ISP2401) 1690 - __wdt_on_master_slave_sensor(isp, wdt_duration); 1691 - else 1692 - __wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, true); 1693 1979 goto start_delay_wq; 1694 1980 } else if (asd->depth_mode->val && (atomisp_streaming_count(isp) < 1695 1981 ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) { 1696 - if (IS_ISP2401) 1697 - __wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, false); 1698 1982 goto start_delay_wq; 1699 1983 } 1700 1984 ··· 1703 1999 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1704 2000 video, s_stream, 1); 1705 2001 if (ret) { 2002 + spin_lock_irqsave(&isp->lock, irqflags); 1706 2003 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 1707 - ret = -EINVAL; 1708 - goto out; 1709 - } 1710 - 1711 - if (!IS_ISP2401) { 1712 - if (atomisp_buffers_queued(asd)) 1713 - atomisp_wdt_refresh(asd, wdt_duration); 1714 - } else { 1715 - if (atomisp_buffers_queued_pipe(pipe)) 1716 - atomisp_wdt_refresh_pipe(pipe, wdt_duration); 2004 + spin_unlock_irqrestore(&isp->lock, irqflags); 2005 + return -EINVAL; 1717 2006 } 1718 2007 1719 2008 start_delay_wq: 1720 2009 if (asd->continuous_mode->val) { 1721 - struct v4l2_mbus_framefmt *sink; 1722 - 1723 - sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL, 1724 - V4L2_SUBDEV_FORMAT_ACTIVE, 1725 - ATOMISP_SUBDEV_PAD_SINK); 2010 + atomisp_subdev_get_ffmt(&asd->subdev, NULL, 2011 + V4L2_SUBDEV_FORMAT_ACTIVE, 2012 + ATOMISP_SUBDEV_PAD_SINK); 1726 2013 1727 2014 reinit_completion(&asd->init_done); 1728 2015 asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED; 1729 2016 queue_work(asd->delayed_init_workq, &asd->delayed_init_work); 1730 - atomisp_css_set_cont_prev_start_time(isp, 1731 - ATOMISP_CALC_CSS_PREV_OVERLAP(sink->height)); 1732 2017 } else { 1733 2018 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; 1734 2019 } 1735 - out: 1736 - rt_mutex_unlock(&isp->mutex); 1737 - return ret; 2020 + 2021 + return 0; 1738 2022 } 1739 2023 1740 - int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) 2024 + int atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) 1741 2025 { 1742 2026 struct video_device *vdev = video_devdata(file); 1743 2027 struct atomisp_device *isp = video_get_drvdata(vdev); ··· 1742 2050 unsigned long flags; 1743 2051 bool first_streamoff = false; 1744 2052 1745 - if (!asd) { 1746 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 1747 - __func__, vdev->name); 1748 - return -EINVAL; 1749 - } 1750 - 1751 2053 dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n", 1752 2054 atomisp_subdev_source_pad(vdev), asd->index); 1753 2055 1754 2056 lockdep_assert_held(&isp->mutex); 1755 - lockdep_assert_held(&isp->streamoff_mutex); 1756 2057 1757 2058 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1758 2059 dev_dbg(isp->dev, "unsupported v4l2 buf type\n"); ··· 1756 2071 * do only videobuf_streamoff for capture & vf pipes in 1757 2072 * case of continuous capture 1758 2073 */ 1759 - if ((asd->continuous_mode->val || 1760 - isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) && 1761 - atomisp_subdev_source_pad(vdev) != 1762 - ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && 1763 - atomisp_subdev_source_pad(vdev) != 1764 - ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) { 1765 - if (isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) { 1766 - v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1767 - video, s_stream, 0); 1768 - } else if (atomisp_subdev_source_pad(vdev) 1769 - == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) { 2074 + if (asd->continuous_mode->val && 2075 + atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW && 2076 + atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) { 2077 + if (atomisp_subdev_source_pad(vdev) == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) { 1770 2078 /* stop continuous still capture if needed */ 1771 2079 if (asd->params.offline_parm.num_captures == -1) 1772 2080 atomisp_css_offline_capture_configure(asd, ··· 1796 2118 if (!pipe->capq.streaming) 1797 2119 return 0; 1798 2120 1799 - spin_lock_irqsave(&isp->lock, flags); 1800 - if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { 1801 - asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING; 2121 + if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) 1802 2122 first_streamoff = true; 1803 - } 1804 - spin_unlock_irqrestore(&isp->lock, flags); 1805 - 1806 - if (first_streamoff) { 1807 - /* if other streams are running, should not disable watch dog */ 1808 - rt_mutex_unlock(&isp->mutex); 1809 - atomisp_wdt_stop(asd, true); 1810 - 1811 - /* 1812 - * must stop sending pixels into GP_FIFO before stop 1813 - * the pipeline. 1814 - */ 1815 - if (isp->sw_contex.file_input) 1816 - v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1817 - video, s_stream, 0); 1818 - 1819 - rt_mutex_lock(&isp->mutex); 1820 - } 1821 2123 1822 2124 spin_lock_irqsave(&isp->lock, flags); 1823 2125 if (atomisp_subdev_streaming_count(asd) == 1) 1824 2126 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 2127 + else 2128 + asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING; 1825 2129 spin_unlock_irqrestore(&isp->lock, flags); 1826 2130 1827 2131 if (!first_streamoff) { ··· 1814 2154 } 1815 2155 1816 2156 atomisp_clear_css_buffer_counters(asd); 1817 - 1818 - if (!isp->sw_contex.file_input) 1819 - atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1820 - false); 2157 + atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); 1821 2158 1822 2159 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) { 1823 2160 cancel_work_sync(&asd->delayed_init_work); 1824 2161 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED; 1825 2162 } 1826 - if (first_streamoff) { 1827 - css_pipe_id = atomisp_get_css_pipe_id(asd); 1828 - atomisp_css_stop(asd, css_pipe_id, false); 1829 - } 2163 + 2164 + css_pipe_id = atomisp_get_css_pipe_id(asd); 2165 + atomisp_css_stop(asd, css_pipe_id, false); 2166 + 1830 2167 /* cancel work queue*/ 1831 2168 if (asd->video_out_capture.users) { 1832 2169 capture_pipe = &asd->video_out_capture; ··· 1867 2210 != atomisp_sensor_start_stream(asd)) 1868 2211 return 0; 1869 2212 1870 - if (!isp->sw_contex.file_input) 1871 - ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1872 - video, s_stream, 0); 2213 + ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 2214 + video, s_stream, 0); 1873 2215 1874 2216 if (isp->flash) { 1875 2217 asd->params.num_flash_frames = 0; ··· 1940 2284 return ret; 1941 2285 } 1942 2286 1943 - static int atomisp_streamoff(struct file *file, void *fh, 1944 - enum v4l2_buf_type type) 1945 - { 1946 - struct video_device *vdev = video_devdata(file); 1947 - struct atomisp_device *isp = video_get_drvdata(vdev); 1948 - int rval; 1949 - 1950 - mutex_lock(&isp->streamoff_mutex); 1951 - rt_mutex_lock(&isp->mutex); 1952 - rval = __atomisp_streamoff(file, fh, type); 1953 - rt_mutex_unlock(&isp->mutex); 1954 - mutex_unlock(&isp->streamoff_mutex); 1955 - 1956 - return rval; 1957 - } 1958 - 1959 2287 /* 1960 2288 * To get the current value of a control. 1961 2289 * applications initialize the id field of a struct v4l2_control and ··· 1953 2313 struct atomisp_device *isp = video_get_drvdata(vdev); 1954 2314 int i, ret = -EINVAL; 1955 2315 1956 - if (!asd) { 1957 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 1958 - __func__, vdev->name); 1959 - return -EINVAL; 1960 - } 1961 - 1962 2316 for (i = 0; i < ctrls_num; i++) { 1963 2317 if (ci_v4l2_controls[i].id == control->id) { 1964 2318 ret = 0; ··· 1962 2328 1963 2329 if (ret) 1964 2330 return ret; 1965 - 1966 - rt_mutex_lock(&isp->mutex); 1967 2331 1968 2332 switch (control->id) { 1969 2333 case V4L2_CID_IRIS_ABSOLUTE: ··· 1984 2352 case V4L2_CID_TEST_PATTERN_COLOR_GR: 1985 2353 case V4L2_CID_TEST_PATTERN_COLOR_GB: 1986 2354 case V4L2_CID_TEST_PATTERN_COLOR_B: 1987 - rt_mutex_unlock(&isp->mutex); 1988 2355 return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera-> 1989 2356 ctrl_handler, control); 1990 2357 case V4L2_CID_COLORFX: ··· 2012 2381 break; 2013 2382 } 2014 2383 2015 - rt_mutex_unlock(&isp->mutex); 2016 2384 return ret; 2017 2385 } 2018 2386 ··· 2028 2398 struct atomisp_device *isp = video_get_drvdata(vdev); 2029 2399 int i, ret = -EINVAL; 2030 2400 2031 - if (!asd) { 2032 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2033 - __func__, vdev->name); 2034 - return -EINVAL; 2035 - } 2036 - 2037 2401 for (i = 0; i < ctrls_num; i++) { 2038 2402 if (ci_v4l2_controls[i].id == control->id) { 2039 2403 ret = 0; ··· 2038 2414 if (ret) 2039 2415 return ret; 2040 2416 2041 - rt_mutex_lock(&isp->mutex); 2042 2417 switch (control->id) { 2043 2418 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: 2044 2419 case V4L2_CID_EXPOSURE: ··· 2058 2435 case V4L2_CID_TEST_PATTERN_COLOR_GR: 2059 2436 case V4L2_CID_TEST_PATTERN_COLOR_GB: 2060 2437 case V4L2_CID_TEST_PATTERN_COLOR_B: 2061 - rt_mutex_unlock(&isp->mutex); 2062 2438 return v4l2_s_ctrl(NULL, 2063 2439 isp->inputs[asd->input_curr].camera-> 2064 2440 ctrl_handler, control); ··· 2089 2467 ret = -EINVAL; 2090 2468 break; 2091 2469 } 2092 - rt_mutex_unlock(&isp->mutex); 2093 2470 return ret; 2094 2471 } 2095 2472 ··· 2105 2484 struct video_device *vdev = video_devdata(file); 2106 2485 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 2107 2486 struct atomisp_device *isp = video_get_drvdata(vdev); 2108 - 2109 - if (!asd) { 2110 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2111 - __func__, vdev->name); 2112 - return -EINVAL; 2113 - } 2114 2487 2115 2488 switch (qc->id) { 2116 2489 case V4L2_CID_FOCUS_ABSOLUTE: ··· 2150 2535 struct v4l2_control ctrl; 2151 2536 int i; 2152 2537 int ret = 0; 2153 - 2154 - if (!asd) { 2155 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2156 - __func__, vdev->name); 2157 - return -EINVAL; 2158 - } 2159 2538 2160 2539 if (!IS_ISP2401) 2161 2540 motor = isp->inputs[asd->input_curr].motor; ··· 2201 2592 &ctrl); 2202 2593 break; 2203 2594 case V4L2_CID_ZOOM_ABSOLUTE: 2204 - rt_mutex_lock(&isp->mutex); 2205 2595 ret = atomisp_digital_zoom(asd, 0, &ctrl.value); 2206 - rt_mutex_unlock(&isp->mutex); 2207 2596 break; 2208 2597 case V4L2_CID_G_SKIP_FRAMES: 2209 2598 ret = v4l2_subdev_call( ··· 2260 2653 int i; 2261 2654 int ret = 0; 2262 2655 2263 - if (!asd) { 2264 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2265 - __func__, vdev->name); 2266 - return -EINVAL; 2267 - } 2268 - 2269 2656 if (!IS_ISP2401) 2270 2657 motor = isp->inputs[asd->input_curr].motor; 2271 2658 else ··· 2308 2707 case V4L2_CID_FLASH_STROBE: 2309 2708 case V4L2_CID_FLASH_MODE: 2310 2709 case V4L2_CID_FLASH_STATUS_REGISTER: 2311 - rt_mutex_lock(&isp->mutex); 2312 2710 if (isp->flash) { 2313 2711 ret = 2314 2712 v4l2_s_ctrl(NULL, isp->flash->ctrl_handler, ··· 2322 2722 asd->params.num_flash_frames = 0; 2323 2723 } 2324 2724 } 2325 - rt_mutex_unlock(&isp->mutex); 2326 2725 break; 2327 2726 case V4L2_CID_ZOOM_ABSOLUTE: 2328 - rt_mutex_lock(&isp->mutex); 2329 2727 ret = atomisp_digital_zoom(asd, 1, &ctrl.value); 2330 - rt_mutex_unlock(&isp->mutex); 2331 2728 break; 2332 2729 default: 2333 2730 ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id); ··· 2381 2784 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 2382 2785 struct atomisp_device *isp = video_get_drvdata(vdev); 2383 2786 2384 - if (!asd) { 2385 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2386 - __func__, vdev->name); 2387 - return -EINVAL; 2388 - } 2389 - 2390 2787 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 2391 2788 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 2392 2789 return -EINVAL; 2393 2790 } 2394 2791 2395 - rt_mutex_lock(&isp->mutex); 2396 2792 parm->parm.capture.capturemode = asd->run_mode->val; 2397 - rt_mutex_unlock(&isp->mutex); 2398 2793 2399 2794 return 0; 2400 2795 } ··· 2401 2812 int rval; 2402 2813 int fps; 2403 2814 2404 - if (!asd) { 2405 - dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", 2406 - __func__, vdev->name); 2407 - return -EINVAL; 2408 - } 2409 - 2410 2815 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 2411 2816 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 2412 2817 return -EINVAL; 2413 2818 } 2414 - 2415 - rt_mutex_lock(&isp->mutex); 2416 2819 2417 2820 asd->high_speed_mode = false; 2418 2821 switch (parm->parm.capture.capturemode) { ··· 2424 2843 asd->high_speed_mode = true; 2425 2844 } 2426 2845 2427 - goto out; 2846 + return rval == -ENOIOCTLCMD ? 0 : rval; 2428 2847 } 2429 2848 case CI_MODE_VIDEO: 2430 2849 mode = ATOMISP_RUN_MODE_VIDEO; ··· 2439 2858 mode = ATOMISP_RUN_MODE_PREVIEW; 2440 2859 break; 2441 2860 default: 2442 - rval = -EINVAL; 2443 - goto out; 2861 + return -EINVAL; 2444 2862 } 2445 2863 2446 2864 rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode); 2447 2865 2448 - out: 2449 - rt_mutex_unlock(&isp->mutex); 2450 - 2451 2866 return rval == -ENOIOCTLCMD ? 0 : rval; 2452 - } 2453 - 2454 - static int atomisp_s_parm_file(struct file *file, void *fh, 2455 - struct v4l2_streamparm *parm) 2456 - { 2457 - struct video_device *vdev = video_devdata(file); 2458 - struct atomisp_device *isp = video_get_drvdata(vdev); 2459 - 2460 - if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { 2461 - dev_err(isp->dev, "unsupported v4l2 buf type for output\n"); 2462 - return -EINVAL; 2463 - } 2464 - 2465 - rt_mutex_lock(&isp->mutex); 2466 - isp->sw_contex.file_input = true; 2467 - rt_mutex_unlock(&isp->mutex); 2468 - 2469 - return 0; 2470 2867 } 2471 2868 2472 2869 static long atomisp_vidioc_default(struct file *file, void *fh, ··· 2452 2893 { 2453 2894 struct video_device *vdev = video_devdata(file); 2454 2895 struct atomisp_device *isp = video_get_drvdata(vdev); 2455 - struct atomisp_sub_device *asd; 2896 + struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 2456 2897 struct v4l2_subdev *motor; 2457 - bool acc_node; 2458 2898 int err; 2459 - 2460 - acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC"); 2461 - if (acc_node) 2462 - asd = atomisp_to_acc_pipe(vdev)->asd; 2463 - else 2464 - asd = atomisp_to_video_pipe(vdev)->asd; 2465 2899 2466 2900 if (!IS_ISP2401) 2467 2901 motor = isp->inputs[asd->input_curr].motor; 2468 2902 else 2469 2903 motor = isp->motor; 2470 2904 2471 - switch (cmd) { 2472 - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: 2473 - case ATOMISP_IOC_S_EXPOSURE: 2474 - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP: 2475 - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: 2476 - case ATOMISP_IOC_EXT_ISP_CTRL: 2477 - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO: 2478 - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE: 2479 - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE: 2480 - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT: 2481 - case ATOMISP_IOC_S_SENSOR_EE_CONFIG: 2482 - case ATOMISP_IOC_G_UPDATE_EXPOSURE: 2483 - /* we do not need take isp->mutex for these IOCTLs */ 2484 - break; 2485 - default: 2486 - rt_mutex_lock(&isp->mutex); 2487 - break; 2488 - } 2489 2905 switch (cmd) { 2490 2906 case ATOMISP_IOC_S_SENSOR_RUNMODE: 2491 2907 if (IS_ISP2401) ··· 2707 3173 break; 2708 3174 } 2709 3175 2710 - switch (cmd) { 2711 - case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: 2712 - case ATOMISP_IOC_S_EXPOSURE: 2713 - case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP: 2714 - case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: 2715 - case ATOMISP_IOC_EXT_ISP_CTRL: 2716 - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO: 2717 - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE: 2718 - case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE: 2719 - case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT: 2720 - case ATOMISP_IOC_G_UPDATE_EXPOSURE: 2721 - break; 2722 - default: 2723 - rt_mutex_unlock(&isp->mutex); 2724 - break; 2725 - } 2726 3176 return err; 2727 3177 } 2728 3178 ··· 2725 3207 .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap, 2726 3208 .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap, 2727 3209 .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap, 2728 - .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap, 3210 + .vidioc_s_fmt_vid_cap = atomisp_set_fmt, 2729 3211 .vidioc_reqbufs = atomisp_reqbufs, 2730 3212 .vidioc_querybuf = atomisp_querybuf, 2731 3213 .vidioc_qbuf = atomisp_qbuf, ··· 2735 3217 .vidioc_default = atomisp_vidioc_default, 2736 3218 .vidioc_s_parm = atomisp_s_parm, 2737 3219 .vidioc_g_parm = atomisp_g_parm, 2738 - }; 2739 - 2740 - const struct v4l2_ioctl_ops atomisp_file_ioctl_ops = { 2741 - .vidioc_querycap = atomisp_querycap, 2742 - .vidioc_g_fmt_vid_out = atomisp_g_fmt_file, 2743 - .vidioc_s_fmt_vid_out = atomisp_s_fmt_file, 2744 - .vidioc_s_parm = atomisp_s_parm_file, 2745 - .vidioc_reqbufs = atomisp_reqbufs_file, 2746 - .vidioc_querybuf = atomisp_querybuf_file, 2747 - .vidioc_qbuf = atomisp_qbuf_file, 2748 3220 };
+4 -10
drivers/staging/media/atomisp/pci/atomisp_ioctl.h
··· 34 34 const struct 35 35 atomisp_format_bridge *atomisp_get_format_bridge_from_mbus(u32 mbus_code); 36 36 37 + int atomisp_pipe_check(struct atomisp_video_pipe *pipe, bool streaming_ok); 38 + 37 39 int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, 38 40 uint16_t stream_id); 39 41 40 - int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type); 41 - int __atomisp_reqbufs(struct file *file, void *fh, 42 - struct v4l2_requestbuffers *req); 43 - 44 - int atomisp_reqbufs(struct file *file, void *fh, 45 - struct v4l2_requestbuffers *req); 42 + int atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type); 43 + int atomisp_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req); 46 44 47 45 enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device 48 46 *asd); 49 47 50 48 void atomisp_videobuf_free_buf(struct videobuf_buffer *vb); 51 49 52 - extern const struct v4l2_file_operations atomisp_file_fops; 53 - 54 50 extern const struct v4l2_ioctl_ops atomisp_ioctl_ops; 55 - 56 - extern const struct v4l2_ioctl_ops atomisp_file_ioctl_ops; 57 51 58 52 unsigned int atomisp_streaming_count(struct atomisp_device *isp); 59 53
+36 -97
drivers/staging/media/atomisp/pci/atomisp_subdev.c
··· 373 373 struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd); 374 374 struct atomisp_device *isp = isp_sd->isp; 375 375 struct v4l2_mbus_framefmt *ffmt[ATOMISP_SUBDEV_PADS_NUM]; 376 - u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode); 377 376 struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM], 378 377 *comp[ATOMISP_SUBDEV_PADS_NUM]; 379 - enum atomisp_input_stream_id stream_id; 380 378 unsigned int i; 381 379 unsigned int padding_w = pad_w; 382 380 unsigned int padding_h = pad_h; 383 - 384 - stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad); 385 381 386 382 isp_get_fmt_rect(sd, sd_state, which, ffmt, crop, comp); 387 383 ··· 474 478 dvs_w = dvs_h = 0; 475 479 } 476 480 atomisp_css_video_set_dis_envelope(isp_sd, dvs_w, dvs_h); 477 - atomisp_css_input_set_effective_resolution(isp_sd, stream_id, 478 - crop[pad]->width, crop[pad]->height); 479 - 481 + atomisp_css_input_set_effective_resolution(isp_sd, 482 + ATOMISP_INPUT_STREAM_GENERAL, 483 + crop[pad]->width, 484 + crop[pad]->height); 480 485 break; 481 486 } 482 487 case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE: ··· 520 523 if (r->width * crop[ATOMISP_SUBDEV_PAD_SINK]->height < 521 524 crop[ATOMISP_SUBDEV_PAD_SINK]->width * r->height) 522 525 atomisp_css_input_set_effective_resolution(isp_sd, 523 - stream_id, 526 + ATOMISP_INPUT_STREAM_GENERAL, 524 527 rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]-> 525 528 height * r->width / r->height, 526 529 ATOM_ISP_STEP_WIDTH), 527 530 crop[ATOMISP_SUBDEV_PAD_SINK]->height); 528 531 else 529 532 atomisp_css_input_set_effective_resolution(isp_sd, 530 - stream_id, 533 + ATOMISP_INPUT_STREAM_GENERAL, 531 534 crop[ATOMISP_SUBDEV_PAD_SINK]->width, 532 535 rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]-> 533 536 width * r->height / r->width, ··· 617 620 struct atomisp_device *isp = isp_sd->isp; 618 621 struct v4l2_mbus_framefmt *__ffmt = 619 622 atomisp_subdev_get_ffmt(sd, sd_state, which, pad); 620 - u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode); 621 - enum atomisp_input_stream_id stream_id; 622 623 623 624 dev_dbg(isp->dev, "ffmt: pad %s w %d h %d code 0x%8.8x which %s\n", 624 625 atomisp_pad_str(pad), ffmt->width, ffmt->height, ffmt->code, 625 626 which == V4L2_SUBDEV_FORMAT_TRY ? "V4L2_SUBDEV_FORMAT_TRY" 626 627 : "V4L2_SUBDEV_FORMAT_ACTIVE"); 627 - 628 - stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad); 629 628 630 629 switch (pad) { 631 630 case ATOMISP_SUBDEV_PAD_SINK: { ··· 642 649 643 650 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { 644 651 atomisp_css_input_set_resolution(isp_sd, 645 - stream_id, ffmt); 652 + ATOMISP_INPUT_STREAM_GENERAL, ffmt); 646 653 atomisp_css_input_set_binning_factor(isp_sd, 647 - stream_id, 654 + ATOMISP_INPUT_STREAM_GENERAL, 648 655 atomisp_get_sensor_bin_factor(isp_sd)); 649 - atomisp_css_input_set_bayer_order(isp_sd, stream_id, 656 + atomisp_css_input_set_bayer_order(isp_sd, ATOMISP_INPUT_STREAM_GENERAL, 650 657 fc->bayer_order); 651 - atomisp_css_input_set_format(isp_sd, stream_id, 658 + atomisp_css_input_set_format(isp_sd, ATOMISP_INPUT_STREAM_GENERAL, 652 659 fc->atomisp_in_fmt); 653 - atomisp_css_set_default_isys_config(isp_sd, stream_id, 660 + atomisp_css_set_default_isys_config(isp_sd, ATOMISP_INPUT_STREAM_GENERAL, 654 661 ffmt); 655 662 } 656 663 ··· 867 874 { 868 875 struct atomisp_sub_device *asd = container_of( 869 876 ctrl->handler, struct atomisp_sub_device, ctrl_handler); 877 + unsigned int streaming; 878 + unsigned long flags; 870 879 871 880 switch (ctrl->id) { 872 881 case V4L2_CID_RUN_MODE: 873 882 return __atomisp_update_run_mode(asd); 874 883 case V4L2_CID_DEPTH_MODE: 875 - if (asd->streaming != ATOMISP_DEVICE_STREAMING_DISABLED) { 884 + /* Use spinlock instead of mutex to avoid possible locking issues */ 885 + spin_lock_irqsave(&asd->isp->lock, flags); 886 + streaming = asd->streaming; 887 + spin_unlock_irqrestore(&asd->isp->lock, flags); 888 + if (streaming != ATOMISP_DEVICE_STREAMING_DISABLED) { 876 889 dev_err(asd->isp->dev, 877 890 "ISP is streaming, it is not supported to change the depth mode\n"); 878 891 return -EINVAL; ··· 1065 1066 pipe->isp = asd->isp; 1066 1067 spin_lock_init(&pipe->irq_lock); 1067 1068 INIT_LIST_HEAD(&pipe->activeq); 1068 - INIT_LIST_HEAD(&pipe->activeq_out); 1069 1069 INIT_LIST_HEAD(&pipe->buffers_waiting_for_param); 1070 1070 INIT_LIST_HEAD(&pipe->per_frame_params); 1071 1071 memset(pipe->frame_request_config_id, ··· 1072 1074 memset(pipe->frame_params, 1073 1075 0, VIDEO_MAX_FRAME * 1074 1076 sizeof(struct atomisp_css_params_with_list *)); 1075 - } 1076 - 1077 - static void atomisp_init_acc_pipe(struct atomisp_sub_device *asd, 1078 - struct atomisp_acc_pipe *pipe) 1079 - { 1080 - pipe->asd = asd; 1081 - pipe->isp = asd->isp; 1082 1077 } 1083 1078 1084 1079 /* ··· 1117 1126 if (ret < 0) 1118 1127 return ret; 1119 1128 1120 - atomisp_init_subdev_pipe(asd, &asd->video_in, 1121 - V4L2_BUF_TYPE_VIDEO_OUTPUT); 1122 - 1123 1129 atomisp_init_subdev_pipe(asd, &asd->video_out_preview, 1124 1130 V4L2_BUF_TYPE_VIDEO_CAPTURE); 1125 1131 ··· 1128 1140 1129 1141 atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture, 1130 1142 V4L2_BUF_TYPE_VIDEO_CAPTURE); 1131 - 1132 - atomisp_init_acc_pipe(asd, &asd->video_acc); 1133 - 1134 - ret = atomisp_video_init(&asd->video_in, "MEMORY", 1135 - ATOMISP_RUN_MODE_SDV); 1136 - if (ret < 0) 1137 - return ret; 1138 1143 1139 1144 ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE", 1140 1145 ATOMISP_RUN_MODE_STILL_CAPTURE); ··· 1148 1167 ATOMISP_RUN_MODE_VIDEO); 1149 1168 if (ret < 0) 1150 1169 return ret; 1151 - 1152 - atomisp_acc_init(&asd->video_acc, "ACC"); 1153 1170 1154 1171 ret = v4l2_ctrl_handler_init(&asd->ctrl_handler, 1); 1155 1172 if (ret) ··· 1205 1226 return ret; 1206 1227 } 1207 1228 } 1208 - for (i = 0; i < isp->input_cnt - 2; i++) { 1229 + for (i = 0; i < isp->input_cnt; i++) { 1230 + /* Don't create links for the test-pattern-generator */ 1231 + if (isp->inputs[i].type == TEST_PATTERN) 1232 + continue; 1233 + 1209 1234 ret = media_create_pad_link(&isp->inputs[i].camera->entity, 0, 1210 1235 &isp->csi2_port[isp->inputs[i]. 1211 1236 port].subdev.entity, ··· 1245 1262 entity, 0, 0); 1246 1263 if (ret < 0) 1247 1264 return ret; 1248 - /* 1249 - * file input only supported on subdev0 1250 - * so do not create pad link for subdevs other then subdev0 1251 - */ 1252 - if (asd->index) 1253 - return 0; 1254 - ret = media_create_pad_link(&asd->video_in.vdev.entity, 1255 - 0, &asd->subdev.entity, 1256 - ATOMISP_SUBDEV_PAD_SINK, 0); 1257 - if (ret < 0) 1258 - return ret; 1259 1265 } 1260 1266 return 0; 1261 1267 } ··· 1274 1302 { 1275 1303 atomisp_subdev_cleanup_entities(asd); 1276 1304 v4l2_device_unregister_subdev(&asd->subdev); 1277 - atomisp_video_unregister(&asd->video_in); 1278 1305 atomisp_video_unregister(&asd->video_out_preview); 1279 1306 atomisp_video_unregister(&asd->video_out_vf); 1280 1307 atomisp_video_unregister(&asd->video_out_capture); 1281 1308 atomisp_video_unregister(&asd->video_out_video_capture); 1282 - atomisp_acc_unregister(&asd->video_acc); 1283 1309 } 1284 1310 1285 - int atomisp_subdev_register_entities(struct atomisp_sub_device *asd, 1286 - struct v4l2_device *vdev) 1311 + int atomisp_subdev_register_subdev(struct atomisp_sub_device *asd, 1312 + struct v4l2_device *vdev) 1313 + { 1314 + return v4l2_device_register_subdev(vdev, &asd->subdev); 1315 + } 1316 + 1317 + int atomisp_subdev_register_video_nodes(struct atomisp_sub_device *asd, 1318 + struct v4l2_device *vdev) 1287 1319 { 1288 1320 int ret; 1289 - u32 device_caps; 1290 1321 1291 1322 /* 1292 1323 * FIXME: check if all device caps are properly initialized. 1293 - * Should any of those use V4L2_CAP_META_OUTPUT? Probably yes. 1324 + * Should any of those use V4L2_CAP_META_CAPTURE? Probably yes. 1294 1325 */ 1295 1326 1296 - device_caps = V4L2_CAP_VIDEO_CAPTURE | 1297 - V4L2_CAP_STREAMING; 1298 - 1299 - /* Register the subdev and video node. */ 1300 - 1301 - ret = v4l2_device_register_subdev(vdev, &asd->subdev); 1302 - if (ret < 0) 1303 - goto error; 1304 - 1305 1327 asd->video_out_preview.vdev.v4l2_dev = vdev; 1306 - asd->video_out_preview.vdev.device_caps = device_caps | 1307 - V4L2_CAP_VIDEO_OUTPUT; 1328 + asd->video_out_preview.vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1308 1329 ret = video_register_device(&asd->video_out_preview.vdev, 1309 1330 VFL_TYPE_VIDEO, -1); 1310 1331 if (ret < 0) 1311 1332 goto error; 1312 1333 1313 1334 asd->video_out_capture.vdev.v4l2_dev = vdev; 1314 - asd->video_out_capture.vdev.device_caps = device_caps | 1315 - V4L2_CAP_VIDEO_OUTPUT; 1335 + asd->video_out_capture.vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1316 1336 ret = video_register_device(&asd->video_out_capture.vdev, 1317 1337 VFL_TYPE_VIDEO, -1); 1318 1338 if (ret < 0) 1319 1339 goto error; 1320 1340 1321 1341 asd->video_out_vf.vdev.v4l2_dev = vdev; 1322 - asd->video_out_vf.vdev.device_caps = device_caps | 1323 - V4L2_CAP_VIDEO_OUTPUT; 1342 + asd->video_out_vf.vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1324 1343 ret = video_register_device(&asd->video_out_vf.vdev, 1325 1344 VFL_TYPE_VIDEO, -1); 1326 1345 if (ret < 0) 1327 1346 goto error; 1328 1347 1329 1348 asd->video_out_video_capture.vdev.v4l2_dev = vdev; 1330 - asd->video_out_video_capture.vdev.device_caps = device_caps | 1331 - V4L2_CAP_VIDEO_OUTPUT; 1349 + asd->video_out_video_capture.vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1332 1350 ret = video_register_device(&asd->video_out_video_capture.vdev, 1333 - VFL_TYPE_VIDEO, -1); 1334 - if (ret < 0) 1335 - goto error; 1336 - asd->video_acc.vdev.v4l2_dev = vdev; 1337 - asd->video_acc.vdev.device_caps = device_caps | 1338 - V4L2_CAP_VIDEO_OUTPUT; 1339 - ret = video_register_device(&asd->video_acc.vdev, 1340 - VFL_TYPE_VIDEO, -1); 1341 - if (ret < 0) 1342 - goto error; 1343 - 1344 - /* 1345 - * file input only supported on subdev0 1346 - * so do not create video node for subdevs other then subdev0 1347 - */ 1348 - if (asd->index) 1349 - return 0; 1350 - 1351 - asd->video_in.vdev.v4l2_dev = vdev; 1352 - asd->video_in.vdev.device_caps = device_caps | 1353 - V4L2_CAP_VIDEO_CAPTURE; 1354 - ret = video_register_device(&asd->video_in.vdev, 1355 1351 VFL_TYPE_VIDEO, -1); 1356 1352 if (ret < 0) 1357 1353 goto error; ··· 1355 1415 return -ENOMEM; 1356 1416 for (i = 0; i < isp->num_of_streams; i++) { 1357 1417 asd = &isp->asd[i]; 1358 - spin_lock_init(&asd->lock); 1359 1418 asd->isp = isp; 1360 1419 isp_subdev_init_params(asd); 1361 1420 asd->index = i;
+13 -58
drivers/staging/media/atomisp/pci/atomisp_subdev.h
··· 70 70 enum v4l2_buf_type type; 71 71 struct media_pad pad; 72 72 struct videobuf_queue capq; 73 - struct videobuf_queue outq; 74 73 struct list_head activeq; 75 - struct list_head activeq_out; 76 74 /* 77 75 * the buffers waiting for per-frame parameters, this is only valid 78 76 * in per-frame setting mode. ··· 84 86 85 87 unsigned int buffers_in_css; 86 88 87 - /* irq_lock is used to protect video buffer state change operations and 88 - * also to make activeq, activeq_out, capq and outq list 89 - * operations atomic. */ 89 + /* 90 + * irq_lock is used to protect video buffer state change operations and 91 + * also to make activeq and capq operations atomic. 92 + */ 90 93 spinlock_t irq_lock; 91 94 unsigned int users; 92 95 ··· 108 109 */ 109 110 unsigned int frame_request_config_id[VIDEO_MAX_FRAME]; 110 111 struct atomisp_css_params_with_list *frame_params[VIDEO_MAX_FRAME]; 111 - 112 - /* 113 - * move wdt from asd struct to create wdt for each pipe 114 - */ 115 - /* ISP2401 */ 116 - struct timer_list wdt; 117 - unsigned int wdt_duration; /* in jiffies */ 118 - unsigned long wdt_expires; 119 - atomic_t wdt_count; 120 - }; 121 - 122 - struct atomisp_acc_pipe { 123 - struct video_device vdev; 124 - unsigned int users; 125 - bool running; 126 - struct atomisp_sub_device *asd; 127 - struct atomisp_device *isp; 128 112 }; 129 113 130 114 struct atomisp_pad_format { ··· 249 267 struct list_head list; 250 268 }; 251 269 252 - struct atomisp_acc_fw { 253 - struct ia_css_fw_info *fw; 254 - unsigned int handle; 255 - unsigned int flags; 256 - unsigned int type; 257 - struct { 258 - size_t length; 259 - unsigned long css_ptr; 260 - } args[ATOMISP_ACC_NR_MEMORY]; 261 - struct list_head list; 262 - }; 263 - 264 - struct atomisp_map { 265 - ia_css_ptr ptr; 266 - size_t length; 267 - struct list_head list; 268 - /* FIXME: should keep book which maps are currently used 269 - * by binaries and not allow releasing those 270 - * which are in use. Implement by reference counting. 271 - */ 272 - }; 273 - 274 270 struct atomisp_sub_device { 275 271 struct v4l2_subdev subdev; 276 272 struct media_pad pads[ATOMISP_SUBDEV_PADS_NUM]; ··· 257 297 258 298 enum atomisp_subdev_input_entity input; 259 299 unsigned int output; 260 - struct atomisp_video_pipe video_in; 261 300 struct atomisp_video_pipe video_out_capture; /* capture output */ 262 301 struct atomisp_video_pipe video_out_vf; /* viewfinder output */ 263 302 struct atomisp_video_pipe video_out_preview; /* preview output */ 264 - struct atomisp_acc_pipe video_acc; 265 303 /* video pipe main output */ 266 304 struct atomisp_video_pipe video_out_video_capture; 267 305 /* struct isp_subdev_params params; */ 268 - spinlock_t lock; 269 306 struct atomisp_device *isp; 270 307 struct v4l2_ctrl_handler ctrl_handler; 271 308 struct v4l2_ctrl *fmt_auto; ··· 313 356 314 357 /* This field specifies which camera (v4l2 input) is selected. */ 315 358 int input_curr; 316 - /* This field specifies which sensor is being selected when there 317 - are multiple sensors connected to the same MIPI port. */ 318 - int sensor_curr; 319 359 320 360 atomic_t sof_count; 321 361 atomic_t sequence; /* Sequence value that is assigned to buffer. */ 322 362 atomic_t sequence_temp; 323 363 324 - unsigned int streaming; /* Hold both mutex and lock to change this */ 364 + /* 365 + * Writers of streaming must hold both isp->mutex and isp->lock. 366 + * Readers of streaming need to hold only one of the two locks. 367 + */ 368 + unsigned int streaming; 325 369 bool stream_prepared; /* whether css stream is created */ 326 370 327 371 /* subdev index: will be used to show which subdev is holding the ··· 347 389 1]; /* Record each Raw Buffer lock status */ 348 390 int raw_buffer_locked_count; 349 391 spinlock_t raw_buffer_bitmap_lock; 350 - 351 - /* ISP 2400 */ 352 - struct timer_list wdt; 353 - unsigned int wdt_duration; /* in jiffies */ 354 - unsigned long wdt_expires; 355 392 356 393 /* ISP2401 */ 357 394 bool re_trigger_capture; ··· 403 450 void atomisp_subdev_cleanup_pending_events(struct atomisp_sub_device *asd); 404 451 405 452 void atomisp_subdev_unregister_entities(struct atomisp_sub_device *asd); 406 - int atomisp_subdev_register_entities(struct atomisp_sub_device *asd, 407 - struct v4l2_device *vdev); 453 + int atomisp_subdev_register_subdev(struct atomisp_sub_device *asd, 454 + struct v4l2_device *vdev); 455 + int atomisp_subdev_register_video_nodes(struct atomisp_sub_device *asd, 456 + struct v4l2_device *vdev); 408 457 int atomisp_subdev_init(struct atomisp_device *isp); 409 458 void atomisp_subdev_cleanup(struct atomisp_device *isp); 410 459 int atomisp_create_pads_links(struct atomisp_device *isp);
+32 -132
drivers/staging/media/atomisp/pci/atomisp_v4l2.c
··· 34 34 #include "atomisp_cmd.h" 35 35 #include "atomisp_common.h" 36 36 #include "atomisp_fops.h" 37 - #include "atomisp_file.h" 38 37 #include "atomisp_ioctl.h" 39 38 #include "atomisp_internal.h" 40 39 #include "atomisp-regs.h" ··· 441 442 video->pad.flags = MEDIA_PAD_FL_SINK; 442 443 video->vdev.fops = &atomisp_fops; 443 444 video->vdev.ioctl_ops = &atomisp_ioctl_ops; 444 - break; 445 - case V4L2_BUF_TYPE_VIDEO_OUTPUT: 446 - direction = "input"; 447 - video->pad.flags = MEDIA_PAD_FL_SOURCE; 448 - video->vdev.fops = &atomisp_file_fops; 449 - video->vdev.ioctl_ops = &atomisp_file_ioctl_ops; 445 + video->vdev.lock = &video->isp->mutex; 450 446 break; 451 447 default: 452 448 return -EINVAL; ··· 461 467 return 0; 462 468 } 463 469 464 - void atomisp_acc_init(struct atomisp_acc_pipe *video, const char *name) 465 - { 466 - video->vdev.fops = &atomisp_fops; 467 - video->vdev.ioctl_ops = &atomisp_ioctl_ops; 468 - 469 - /* Initialize the video device. */ 470 - snprintf(video->vdev.name, sizeof(video->vdev.name), 471 - "ATOMISP ISP %s", name); 472 - video->vdev.release = video_device_release_empty; 473 - video_set_drvdata(&video->vdev, video->isp); 474 - } 475 - 476 470 void atomisp_video_unregister(struct atomisp_video_pipe *video) 477 471 { 478 472 if (video_is_registered(&video->vdev)) { 479 473 media_entity_cleanup(&video->vdev.entity); 480 474 video_unregister_device(&video->vdev); 481 475 } 482 - } 483 - 484 - void atomisp_acc_unregister(struct atomisp_acc_pipe *video) 485 - { 486 - if (video_is_registered(&video->vdev)) 487 - video_unregister_device(&video->vdev); 488 476 } 489 477 490 478 static int atomisp_save_iunit_reg(struct atomisp_device *isp) ··· 1007 1031 &subdevs->v4l2_subdev.board_info; 1008 1032 struct i2c_adapter *adapter = 1009 1033 i2c_get_adapter(subdevs->v4l2_subdev.i2c_adapter_id); 1010 - int sensor_num, i; 1011 1034 1012 1035 dev_info(isp->dev, "Probing Subdev %s\n", board_info->type); 1013 1036 ··· 1065 1090 * pixel_format. 1066 1091 */ 1067 1092 isp->inputs[isp->input_cnt].frame_size.pixel_format = 0; 1068 - isp->inputs[isp->input_cnt].camera_caps = 1069 - atomisp_get_default_camera_caps(); 1070 - sensor_num = isp->inputs[isp->input_cnt] 1071 - .camera_caps->sensor_num; 1072 1093 isp->input_cnt++; 1073 - for (i = 1; i < sensor_num; i++) { 1074 - if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) { 1075 - dev_warn(isp->dev, 1076 - "atomisp inputs out of range\n"); 1077 - break; 1078 - } 1079 - isp->inputs[isp->input_cnt] = 1080 - isp->inputs[isp->input_cnt - 1]; 1081 - isp->inputs[isp->input_cnt].sensor_index = i; 1082 - isp->input_cnt++; 1083 - } 1084 1094 break; 1085 1095 case CAMERA_MOTOR: 1086 1096 if (isp->motor) { ··· 1118 1158 for (i = 0; i < isp->num_of_streams; i++) 1119 1159 atomisp_subdev_unregister_entities(&isp->asd[i]); 1120 1160 atomisp_tpg_unregister_entities(&isp->tpg); 1121 - atomisp_file_input_unregister_entities(&isp->file_dev); 1122 1161 for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) 1123 1162 atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); 1124 1163 ··· 1169 1210 goto csi_and_subdev_probe_failed; 1170 1211 } 1171 1212 1172 - ret = 1173 - atomisp_file_input_register_entities(&isp->file_dev, &isp->v4l2_dev); 1174 - if (ret < 0) { 1175 - dev_err(isp->dev, "atomisp_file_input_register_entities\n"); 1176 - goto file_input_register_failed; 1177 - } 1178 - 1179 1213 ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev); 1180 1214 if (ret < 0) { 1181 1215 dev_err(isp->dev, "atomisp_tpg_register_entities\n"); ··· 1178 1226 for (i = 0; i < isp->num_of_streams; i++) { 1179 1227 struct atomisp_sub_device *asd = &isp->asd[i]; 1180 1228 1181 - ret = atomisp_subdev_register_entities(asd, &isp->v4l2_dev); 1229 + ret = atomisp_subdev_register_subdev(asd, &isp->v4l2_dev); 1182 1230 if (ret < 0) { 1183 - dev_err(isp->dev, 1184 - "atomisp_subdev_register_entities fail\n"); 1231 + dev_err(isp->dev, "atomisp_subdev_register_subdev fail\n"); 1185 1232 for (; i > 0; i--) 1186 1233 atomisp_subdev_unregister_entities( 1187 1234 &isp->asd[i - 1]); ··· 1218 1267 } 1219 1268 } 1220 1269 1221 - dev_dbg(isp->dev, 1222 - "FILE_INPUT enable, camera_cnt: %d\n", isp->input_cnt); 1223 - isp->inputs[isp->input_cnt].type = FILE_INPUT; 1224 - isp->inputs[isp->input_cnt].port = -1; 1225 - isp->inputs[isp->input_cnt].camera_caps = 1226 - atomisp_get_default_camera_caps(); 1227 - isp->inputs[isp->input_cnt++].camera = &isp->file_dev.sd; 1228 - 1229 1270 if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) { 1230 1271 dev_dbg(isp->dev, 1231 1272 "TPG detected, camera_cnt: %d\n", isp->input_cnt); 1232 1273 isp->inputs[isp->input_cnt].type = TEST_PATTERN; 1233 1274 isp->inputs[isp->input_cnt].port = -1; 1234 - isp->inputs[isp->input_cnt].camera_caps = 1235 - atomisp_get_default_camera_caps(); 1236 1275 isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd; 1237 1276 } else { 1238 1277 dev_warn(isp->dev, "too many atomisp inputs, TPG ignored.\n"); 1239 1278 } 1240 1279 1241 - ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); 1242 - if (ret < 0) 1243 - goto link_failed; 1244 - 1245 - return media_device_register(&isp->media_dev); 1280 + return 0; 1246 1281 1247 1282 link_failed: 1248 1283 for (i = 0; i < isp->num_of_streams; i++) ··· 1241 1304 subdev_register_failed: 1242 1305 atomisp_tpg_unregister_entities(&isp->tpg); 1243 1306 tpg_register_failed: 1244 - atomisp_file_input_unregister_entities(&isp->file_dev); 1245 - file_input_register_failed: 1246 1307 for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) 1247 1308 atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); 1248 1309 csi_and_subdev_probe_failed: ··· 1251 1316 return ret; 1252 1317 } 1253 1318 1319 + static int atomisp_register_device_nodes(struct atomisp_device *isp) 1320 + { 1321 + int i, err; 1322 + 1323 + for (i = 0; i < isp->num_of_streams; i++) { 1324 + err = atomisp_subdev_register_video_nodes(&isp->asd[i], &isp->v4l2_dev); 1325 + if (err) 1326 + return err; 1327 + } 1328 + 1329 + err = atomisp_create_pads_links(isp); 1330 + if (err) 1331 + return err; 1332 + 1333 + err = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); 1334 + if (err) 1335 + return err; 1336 + 1337 + return media_device_register(&isp->media_dev); 1338 + } 1339 + 1254 1340 static int atomisp_initialize_modules(struct atomisp_device *isp) 1255 1341 { 1256 1342 int ret; ··· 1280 1324 if (ret < 0) { 1281 1325 dev_err(isp->dev, "mipi csi2 initialization failed\n"); 1282 1326 goto error_mipi_csi2; 1283 - } 1284 - 1285 - ret = atomisp_file_input_init(isp); 1286 - if (ret < 0) { 1287 - dev_err(isp->dev, 1288 - "file input device initialization failed\n"); 1289 - goto error_file_input; 1290 1327 } 1291 1328 1292 1329 ret = atomisp_tpg_init(isp); ··· 1299 1350 error_isp_subdev: 1300 1351 error_tpg: 1301 1352 atomisp_tpg_cleanup(isp); 1302 - error_file_input: 1303 - atomisp_file_input_cleanup(isp); 1304 1353 error_mipi_csi2: 1305 1354 atomisp_mipi_csi2_cleanup(isp); 1306 1355 return ret; ··· 1307 1360 static void atomisp_uninitialize_modules(struct atomisp_device *isp) 1308 1361 { 1309 1362 atomisp_tpg_cleanup(isp); 1310 - atomisp_file_input_cleanup(isp); 1311 1363 atomisp_mipi_csi2_cleanup(isp); 1312 1364 } 1313 1365 ··· 1416 1470 return true; 1417 1471 } 1418 1472 1419 - static int init_atomisp_wdts(struct atomisp_device *isp) 1420 - { 1421 - int i, err; 1422 - 1423 - atomic_set(&isp->wdt_work_queued, 0); 1424 - isp->wdt_work_queue = alloc_workqueue(isp->v4l2_dev.name, 0, 1); 1425 - if (!isp->wdt_work_queue) { 1426 - dev_err(isp->dev, "Failed to initialize wdt work queue\n"); 1427 - err = -ENOMEM; 1428 - goto alloc_fail; 1429 - } 1430 - INIT_WORK(&isp->wdt_work, atomisp_wdt_work); 1431 - 1432 - for (i = 0; i < isp->num_of_streams; i++) { 1433 - struct atomisp_sub_device *asd = &isp->asd[i]; 1434 - 1435 - if (!IS_ISP2401) { 1436 - timer_setup(&asd->wdt, atomisp_wdt, 0); 1437 - } else { 1438 - timer_setup(&asd->video_out_capture.wdt, 1439 - atomisp_wdt, 0); 1440 - timer_setup(&asd->video_out_preview.wdt, 1441 - atomisp_wdt, 0); 1442 - timer_setup(&asd->video_out_vf.wdt, atomisp_wdt, 0); 1443 - timer_setup(&asd->video_out_video_capture.wdt, 1444 - atomisp_wdt, 0); 1445 - } 1446 - } 1447 - return 0; 1448 - alloc_fail: 1449 - return err; 1450 - } 1451 - 1452 1473 #define ATOM_ISP_PCI_BAR 0 1453 1474 1454 1475 static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ··· 1464 1551 1465 1552 dev_dbg(&pdev->dev, "atomisp mmio base: %p\n", isp->base); 1466 1553 1467 - rt_mutex_init(&isp->mutex); 1468 - rt_mutex_init(&isp->loading); 1469 - mutex_init(&isp->streamoff_mutex); 1554 + mutex_init(&isp->mutex); 1470 1555 spin_lock_init(&isp->lock); 1471 1556 1472 1557 /* This is not a true PCI device on SoC, so the delay is not needed. */ ··· 1636 1725 pci_write_config_dword(pdev, MRFLD_PCI_CSI_AFE_TRIM_CONTROL, csi_afe_trim); 1637 1726 } 1638 1727 1639 - rt_mutex_lock(&isp->loading); 1640 - 1641 1728 err = atomisp_initialize_modules(isp); 1642 1729 if (err < 0) { 1643 1730 dev_err(&pdev->dev, "atomisp_initialize_modules (%d)\n", err); ··· 1647 1738 dev_err(&pdev->dev, "atomisp_register_entities failed (%d)\n", err); 1648 1739 goto register_entities_fail; 1649 1740 } 1650 - err = atomisp_create_pads_links(isp); 1651 - if (err < 0) 1652 - goto register_entities_fail; 1653 - /* init atomisp wdts */ 1654 - err = init_atomisp_wdts(isp); 1655 - if (err != 0) 1656 - goto wdt_work_queue_fail; 1741 + 1742 + INIT_WORK(&isp->assert_recovery_work, atomisp_assert_recovery_work); 1657 1743 1658 1744 /* save the iunit context only once after all the values are init'ed. */ 1659 1745 atomisp_save_iunit_reg(isp); ··· 1681 1777 release_firmware(isp->firmware); 1682 1778 isp->firmware = NULL; 1683 1779 isp->css_env.isp_css_fw.data = NULL; 1684 - isp->ready = true; 1685 - rt_mutex_unlock(&isp->loading); 1780 + 1781 + err = atomisp_register_device_nodes(isp); 1782 + if (err) 1783 + goto css_init_fail; 1686 1784 1687 1785 atomisp_drvfs_init(isp); 1688 1786 ··· 1695 1789 request_irq_fail: 1696 1790 hmm_cleanup(); 1697 1791 pm_runtime_get_noresume(&pdev->dev); 1698 - destroy_workqueue(isp->wdt_work_queue); 1699 - wdt_work_queue_fail: 1700 1792 atomisp_unregister_entities(isp); 1701 1793 register_entities_fail: 1702 1794 atomisp_uninitialize_modules(isp); 1703 1795 initialize_modules_fail: 1704 - rt_mutex_unlock(&isp->loading); 1705 1796 cpu_latency_qos_remove_request(&isp->pm_qos); 1706 1797 atomisp_msi_irq_uninit(isp); 1707 1798 pci_free_irq_vectors(pdev); ··· 1753 1850 1754 1851 atomisp_msi_irq_uninit(isp); 1755 1852 atomisp_unregister_entities(isp); 1756 - 1757 - destroy_workqueue(isp->wdt_work_queue); 1758 - atomisp_file_input_cleanup(isp); 1759 1853 1760 1854 release_firmware(isp->firmware); 1761 1855 }
-3
drivers/staging/media/atomisp/pci/atomisp_v4l2.h
··· 22 22 #define __ATOMISP_V4L2_H__ 23 23 24 24 struct atomisp_video_pipe; 25 - struct atomisp_acc_pipe; 26 25 struct v4l2_device; 27 26 struct atomisp_device; 28 27 struct firmware; 29 28 30 29 int atomisp_video_init(struct atomisp_video_pipe *video, const char *name, 31 30 unsigned int run_mode); 32 - void atomisp_acc_init(struct atomisp_acc_pipe *video, const char *name); 33 31 void atomisp_video_unregister(struct atomisp_video_pipe *video); 34 - void atomisp_acc_unregister(struct atomisp_acc_pipe *video); 35 32 const struct firmware *atomisp_load_firmware(struct atomisp_device *isp); 36 33 int atomisp_csi_lane_config(struct atomisp_device *isp); 37 34
+29 -169
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c
··· 44 44 #include "hmm/hmm_common.h" 45 45 #include "hmm/hmm_bo.h" 46 46 47 - static unsigned int order_to_nr(unsigned int order) 48 - { 49 - return 1U << order; 50 - } 51 - 52 - static unsigned int nr_to_order_bottom(unsigned int nr) 53 - { 54 - return fls(nr) - 1; 55 - } 56 - 57 47 static int __bo_init(struct hmm_bo_device *bdev, struct hmm_buffer_object *bo, 58 48 unsigned int pgnr) 59 49 { ··· 615 625 return bo; 616 626 } 617 627 618 - static void free_private_bo_pages(struct hmm_buffer_object *bo, 619 - int free_pgnr) 628 + static void free_pages_bulk_array(unsigned long nr_pages, struct page **page_array) 620 629 { 621 - int i, ret; 630 + unsigned long i; 622 631 623 - for (i = 0; i < free_pgnr; i++) { 624 - ret = set_pages_wb(bo->pages[i], 1); 625 - if (ret) 626 - dev_err(atomisp_dev, 627 - "set page to WB err ...ret = %d\n", 628 - ret); 629 - /* 630 - W/A: set_pages_wb seldom return value = -EFAULT 631 - indicate that address of page is not in valid 632 - range(0xffff880000000000~0xffffc7ffffffffff) 633 - then, _free_pages would panic; Do not know why page 634 - address be valid,it maybe memory corruption by lowmemory 635 - */ 636 - if (!ret) { 637 - __free_pages(bo->pages[i], 0); 638 - } 639 - } 632 + for (i = 0; i < nr_pages; i++) 633 + __free_pages(page_array[i], 0); 634 + } 635 + 636 + static void free_private_bo_pages(struct hmm_buffer_object *bo) 637 + { 638 + set_pages_array_wb(bo->pages, bo->pgnr); 639 + free_pages_bulk_array(bo->pgnr, bo->pages); 640 640 } 641 641 642 642 /*Allocate pages which will be used only by ISP*/ 643 643 static int alloc_private_pages(struct hmm_buffer_object *bo) 644 644 { 645 + const gfp_t gfp = __GFP_NOWARN | __GFP_RECLAIM | __GFP_FS; 645 646 int ret; 646 - unsigned int pgnr, order, blk_pgnr, alloc_pgnr; 647 - struct page *pages; 648 - gfp_t gfp = GFP_NOWAIT | __GFP_NOWARN; /* REVISIT: need __GFP_FS too? */ 649 - int i, j; 650 - int failure_number = 0; 651 - bool reduce_order = false; 652 - bool lack_mem = true; 653 647 654 - pgnr = bo->pgnr; 648 + ret = alloc_pages_bulk_array(gfp, bo->pgnr, bo->pages); 649 + if (ret != bo->pgnr) { 650 + free_pages_bulk_array(ret, bo->pages); 651 + return -ENOMEM; 652 + } 655 653 656 - i = 0; 657 - alloc_pgnr = 0; 658 - 659 - while (pgnr) { 660 - order = nr_to_order_bottom(pgnr); 661 - /* 662 - * if be short of memory, we will set order to 0 663 - * everytime. 664 - */ 665 - if (lack_mem) 666 - order = HMM_MIN_ORDER; 667 - else if (order > HMM_MAX_ORDER) 668 - order = HMM_MAX_ORDER; 669 - retry: 670 - /* 671 - * When order > HMM_MIN_ORDER, for performance reasons we don't 672 - * want alloc_pages() to sleep. In case it fails and fallbacks 673 - * to HMM_MIN_ORDER or in case the requested order is originally 674 - * the minimum value, we can allow alloc_pages() to sleep for 675 - * robustness purpose. 676 - * 677 - * REVISIT: why __GFP_FS is necessary? 678 - */ 679 - if (order == HMM_MIN_ORDER) { 680 - gfp &= ~GFP_NOWAIT; 681 - gfp |= __GFP_RECLAIM | __GFP_FS; 682 - } 683 - 684 - pages = alloc_pages(gfp, order); 685 - if (unlikely(!pages)) { 686 - /* 687 - * in low memory case, if allocation page fails, 688 - * we turn to try if order=0 allocation could 689 - * succeed. if order=0 fails too, that means there is 690 - * no memory left. 691 - */ 692 - if (order == HMM_MIN_ORDER) { 693 - dev_err(atomisp_dev, 694 - "%s: cannot allocate pages\n", 695 - __func__); 696 - goto cleanup; 697 - } 698 - order = HMM_MIN_ORDER; 699 - failure_number++; 700 - reduce_order = true; 701 - /* 702 - * if fail two times continuously, we think be short 703 - * of memory now. 704 - */ 705 - if (failure_number == 2) { 706 - lack_mem = true; 707 - failure_number = 0; 708 - } 709 - goto retry; 710 - } else { 711 - blk_pgnr = order_to_nr(order); 712 - 713 - /* 714 - * set memory to uncacheable -- UC_MINUS 715 - */ 716 - ret = set_pages_uc(pages, blk_pgnr); 717 - if (ret) { 718 - dev_err(atomisp_dev, 719 - "set page uncacheablefailed.\n"); 720 - 721 - __free_pages(pages, order); 722 - 723 - goto cleanup; 724 - } 725 - 726 - for (j = 0; j < blk_pgnr; j++, i++) { 727 - bo->pages[i] = pages + j; 728 - } 729 - 730 - pgnr -= blk_pgnr; 731 - 732 - /* 733 - * if order is not reduced this time, clear 734 - * failure_number. 735 - */ 736 - if (reduce_order) 737 - reduce_order = false; 738 - else 739 - failure_number = 0; 740 - } 654 + ret = set_pages_array_uc(bo->pages, bo->pgnr); 655 + if (ret) { 656 + dev_err(atomisp_dev, "set pages uncacheable failed.\n"); 657 + free_pages_bulk_array(bo->pgnr, bo->pages); 658 + return ret; 741 659 } 742 660 743 661 return 0; 744 - cleanup: 745 - alloc_pgnr = i; 746 - free_private_bo_pages(bo, alloc_pgnr); 747 - return -ENOMEM; 748 662 } 749 663 750 664 static void free_user_pages(struct hmm_buffer_object *bo, ··· 656 762 { 657 763 int i; 658 764 659 - if (bo->mem_type == HMM_BO_MEM_TYPE_PFN) { 660 - unpin_user_pages(bo->pages, page_nr); 661 - } else { 662 - for (i = 0; i < page_nr; i++) 663 - put_page(bo->pages[i]); 664 - } 765 + for (i = 0; i < page_nr; i++) 766 + put_page(bo->pages[i]); 665 767 } 666 768 667 769 /* ··· 667 777 const void __user *userptr) 668 778 { 669 779 int page_nr; 670 - struct vm_area_struct *vma; 671 - 672 - mutex_unlock(&bo->mutex); 673 - mmap_read_lock(current->mm); 674 - vma = find_vma(current->mm, (unsigned long)userptr); 675 - mmap_read_unlock(current->mm); 676 - if (!vma) { 677 - dev_err(atomisp_dev, "find_vma failed\n"); 678 - mutex_lock(&bo->mutex); 679 - return -EFAULT; 680 - } 681 - mutex_lock(&bo->mutex); 682 - /* 683 - * Handle frame buffer allocated in other kerenl space driver 684 - * and map to user space 685 - */ 686 780 687 781 userptr = untagged_addr(userptr); 688 782 689 - if (vma->vm_flags & (VM_IO | VM_PFNMAP)) { 690 - page_nr = pin_user_pages((unsigned long)userptr, bo->pgnr, 691 - FOLL_LONGTERM | FOLL_WRITE, 692 - bo->pages, NULL); 693 - bo->mem_type = HMM_BO_MEM_TYPE_PFN; 694 - } else { 695 - /*Handle frame buffer allocated in user space*/ 696 - mutex_unlock(&bo->mutex); 697 - page_nr = get_user_pages_fast((unsigned long)userptr, 698 - (int)(bo->pgnr), 1, bo->pages); 699 - mutex_lock(&bo->mutex); 700 - bo->mem_type = HMM_BO_MEM_TYPE_USER; 701 - } 702 - 703 - dev_dbg(atomisp_dev, "%s: %d %s pages were allocated as 0x%08x\n", 704 - __func__, 705 - bo->pgnr, 706 - bo->mem_type == HMM_BO_MEM_TYPE_USER ? "user" : "pfn", page_nr); 783 + /* Handle frame buffer allocated in user space */ 784 + mutex_unlock(&bo->mutex); 785 + page_nr = get_user_pages_fast((unsigned long)userptr, bo->pgnr, 1, bo->pages); 786 + mutex_lock(&bo->mutex); 707 787 708 788 /* can be written by caller, not forced */ 709 789 if (page_nr != bo->pgnr) { ··· 714 854 mutex_lock(&bo->mutex); 715 855 check_bo_status_no_goto(bo, HMM_BO_PAGE_ALLOCED, status_err); 716 856 717 - bo->pages = kmalloc_array(bo->pgnr, sizeof(struct page *), GFP_KERNEL); 857 + bo->pages = kcalloc(bo->pgnr, sizeof(struct page *), GFP_KERNEL); 718 858 if (unlikely(!bo->pages)) { 719 859 ret = -ENOMEM; 720 860 goto alloc_err; ··· 770 910 bo->status &= (~HMM_BO_PAGE_ALLOCED); 771 911 772 912 if (bo->type == HMM_BO_PRIVATE) 773 - free_private_bo_pages(bo, bo->pgnr); 913 + free_private_bo_pages(bo); 774 914 else if (bo->type == HMM_BO_USER) 775 915 free_user_pages(bo, bo->pgnr); 776 916 else
+2 -2
drivers/staging/media/atomisp/pci/sh_css_params.c
··· 950 950 params->fpn_config.data = NULL; 951 951 } 952 952 if (!params->fpn_config.data) { 953 - params->fpn_config.data = kvmalloc(height * width * 954 - sizeof(short), GFP_KERNEL); 953 + params->fpn_config.data = kvmalloc(array3_size(height, width, sizeof(short)), 954 + GFP_KERNEL); 955 955 if (!params->fpn_config.data) { 956 956 IA_CSS_ERROR("out of memory"); 957 957 IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+4 -4
drivers/staging/media/imx/imx-media-utils.c
··· 863 863 mutex_lock(&imxmd->md.graph_mutex); 864 864 865 865 if (on) { 866 - ret = __media_pipeline_start(entity, &imxmd->pipe); 866 + ret = __media_pipeline_start(entity->pads, &imxmd->pipe); 867 867 if (ret) 868 868 goto out; 869 869 ret = v4l2_subdev_call(sd, video, s_stream, 1); 870 870 if (ret) 871 - __media_pipeline_stop(entity); 871 + __media_pipeline_stop(entity->pads); 872 872 } else { 873 873 v4l2_subdev_call(sd, video, s_stream, 0); 874 - if (entity->pipe) 875 - __media_pipeline_stop(entity); 874 + if (media_pad_pipeline(entity->pads)) 875 + __media_pipeline_stop(entity->pads); 876 876 } 877 877 878 878 out:
+3 -3
drivers/staging/media/imx/imx7-media-csi.c
··· 1360 1360 1361 1361 mutex_lock(&csi->mdev.graph_mutex); 1362 1362 1363 - ret = __media_pipeline_start(&csi->sd.entity, &csi->pipe); 1363 + ret = __video_device_pipeline_start(csi->vdev, &csi->pipe); 1364 1364 if (ret) 1365 1365 goto err_unlock; 1366 1366 ··· 1373 1373 return 0; 1374 1374 1375 1375 err_stop: 1376 - __media_pipeline_stop(&csi->sd.entity); 1376 + __video_device_pipeline_stop(csi->vdev); 1377 1377 err_unlock: 1378 1378 mutex_unlock(&csi->mdev.graph_mutex); 1379 1379 dev_err(csi->dev, "pipeline start failed with %d\n", ret); ··· 1396 1396 1397 1397 mutex_lock(&csi->mdev.graph_mutex); 1398 1398 v4l2_subdev_call(&csi->sd, video, s_stream, 0); 1399 - __media_pipeline_stop(&csi->sd.entity); 1399 + __video_device_pipeline_stop(csi->vdev); 1400 1400 mutex_unlock(&csi->mdev.graph_mutex); 1401 1401 1402 1402 /* release all active buffers */
+5 -2
drivers/staging/media/ipu3/include/uapi/intel-ipu3.h
··· 626 626 * @b: white balance gain for B channel. 627 627 * @gb: white balance gain for Gb channel. 628 628 * 629 - * Precision u3.13, range [0, 8). White balance correction is done by applying 630 - * a multiplicative gain to each color channels prior to BNR. 629 + * For BNR parameters WB gain factor for the three channels [Ggr, Ggb, Gb, Gr]. 630 + * Their precision is U3.13 and the range is (0, 8) and the actual gain is 631 + * Gx + 1, it is typically Gx = 1. 632 + * 633 + * Pout = {Pin * (1 + Gx)}. 631 634 */ 632 635 struct ipu3_uapi_bnr_static_config_wb_gains_config { 633 636 __u16 gr;
+17 -20
drivers/staging/media/ipu3/ipu3-v4l2.c
··· 192 192 struct v4l2_subdev_state *sd_state, 193 193 struct v4l2_subdev_selection *sel) 194 194 { 195 - struct v4l2_rect *try_sel, *r; 196 - struct imgu_v4l2_subdev *imgu_sd = container_of(sd, 197 - struct imgu_v4l2_subdev, 198 - subdev); 195 + struct imgu_v4l2_subdev *imgu_sd = 196 + container_of(sd, struct imgu_v4l2_subdev, subdev); 199 197 200 198 if (sel->pad != IMGU_NODE_IN) 201 199 return -EINVAL; 202 200 203 201 switch (sel->target) { 204 202 case V4L2_SEL_TGT_CROP: 205 - try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad); 206 - r = &imgu_sd->rect.eff; 207 - break; 203 + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) 204 + sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, 205 + sel->pad); 206 + else 207 + sel->r = imgu_sd->rect.eff; 208 + return 0; 208 209 case V4L2_SEL_TGT_COMPOSE: 209 - try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad); 210 - r = &imgu_sd->rect.bds; 211 - break; 210 + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) 211 + sel->r = *v4l2_subdev_get_try_compose(sd, sd_state, 212 + sel->pad); 213 + else 214 + sel->r = imgu_sd->rect.bds; 215 + return 0; 212 216 default: 213 217 return -EINVAL; 214 218 } 215 - 216 - if (sel->which == V4L2_SUBDEV_FORMAT_TRY) 217 - sel->r = *try_sel; 218 - else 219 - sel->r = *r; 220 - 221 - return 0; 222 219 } 223 220 224 221 static int imgu_subdev_set_selection(struct v4l2_subdev *sd, ··· 483 486 pipe = node->pipe; 484 487 imgu_pipe = &imgu->imgu_pipe[pipe]; 485 488 atomic_set(&node->sequence, 0); 486 - r = media_pipeline_start(&node->vdev.entity, &imgu_pipe->pipeline); 489 + r = video_device_pipeline_start(&node->vdev, &imgu_pipe->pipeline); 487 490 if (r < 0) 488 491 goto fail_return_bufs; 489 492 ··· 508 511 return 0; 509 512 510 513 fail_stop_pipeline: 511 - media_pipeline_stop(&node->vdev.entity); 514 + video_device_pipeline_stop(&node->vdev); 512 515 fail_return_bufs: 513 516 imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_QUEUED); 514 517 ··· 548 551 imgu_return_all_buffers(imgu, node, VB2_BUF_STATE_ERROR); 549 552 mutex_unlock(&imgu->streaming_lock); 550 553 551 - media_pipeline_stop(&node->vdev.entity); 554 + video_device_pipeline_stop(&node->vdev); 552 555 } 553 556 554 557 /******************** v4l2_ioctl_ops ********************/
+2
drivers/staging/media/meson/vdec/vdec.c
··· 1102 1102 1103 1103 err_vdev_release: 1104 1104 video_device_release(vdev); 1105 + v4l2_device_unregister(&core->v4l2_dev); 1105 1106 return ret; 1106 1107 } 1107 1108 ··· 1111 1110 struct amvdec_core *core = platform_get_drvdata(pdev); 1112 1111 1113 1112 video_unregister_device(core->vdev_dec); 1113 + v4l2_device_unregister(&core->v4l2_dev); 1114 1114 1115 1115 return 0; 1116 1116 }
+1 -3
drivers/staging/media/omap4iss/iss.c
··· 548 548 struct iss_pipeline *pipe; 549 549 struct media_pad *pad; 550 550 551 - if (!me->pipe) 552 - return 0; 553 551 pipe = to_iss_pipeline(me); 554 - if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED) 552 + if (!pipe || pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED) 555 553 return 0; 556 554 pad = media_pad_remote_pad_first(&pipe->output->pad); 557 555 return pad->entity == me;
+4 -5
drivers/staging/media/omap4iss/iss_video.c
··· 870 870 * Start streaming on the pipeline. No link touching an entity in the 871 871 * pipeline can be activated or deactivated once streaming is started. 872 872 */ 873 - pipe = entity->pipe 874 - ? to_iss_pipeline(entity) : &video->pipe; 873 + pipe = to_iss_pipeline(&video->video.entity) ? : &video->pipe; 875 874 pipe->external = NULL; 876 875 pipe->external_rate = 0; 877 876 pipe->external_bpp = 0; ··· 886 887 if (video->iss->pdata->set_constraints) 887 888 video->iss->pdata->set_constraints(video->iss, true); 888 889 889 - ret = media_pipeline_start(entity, &pipe->pipe); 890 + ret = video_device_pipeline_start(&video->video, &pipe->pipe); 890 891 if (ret < 0) 891 892 goto err_media_pipeline_start; 892 893 ··· 977 978 err_omap4iss_set_stream: 978 979 vb2_streamoff(&vfh->queue, type); 979 980 err_iss_video_check_format: 980 - media_pipeline_stop(&video->video.entity); 981 + video_device_pipeline_stop(&video->video); 981 982 err_media_pipeline_start: 982 983 if (video->iss->pdata->set_constraints) 983 984 video->iss->pdata->set_constraints(video->iss, false); ··· 1031 1032 1032 1033 if (video->iss->pdata->set_constraints) 1033 1034 video->iss->pdata->set_constraints(video->iss, false); 1034 - media_pipeline_stop(&video->video.entity); 1035 + video_device_pipeline_stop(&video->video); 1035 1036 1036 1037 done: 1037 1038 mutex_unlock(&video->stream_lock);
+9 -2
drivers/staging/media/omap4iss/iss_video.h
··· 90 90 int external_bpp; 91 91 }; 92 92 93 - #define to_iss_pipeline(__e) \ 94 - container_of((__e)->pipe, struct iss_pipeline, pipe) 93 + static inline struct iss_pipeline *to_iss_pipeline(struct media_entity *entity) 94 + { 95 + struct media_pipeline *pipe = media_entity_pipeline(entity); 96 + 97 + if (!pipe) 98 + return NULL; 99 + 100 + return container_of(pipe, struct iss_pipeline, pipe); 101 + } 95 102 96 103 static inline int iss_pipeline_ready(struct iss_pipeline *pipe) 97 104 {
+1
drivers/staging/media/sunxi/cedrus/Kconfig
··· 2 2 config VIDEO_SUNXI_CEDRUS 3 3 tristate "Allwinner Cedrus VPU driver" 4 4 depends on VIDEO_DEV 5 + depends on RESET_CONTROLLER 5 6 depends on HAS_DMA 6 7 depends on OF 7 8 select MEDIA_CONTROLLER
+3 -3
drivers/staging/media/tegra-video/tegra210.c
··· 547 547 VI_INCR_SYNCPT_NO_STALL); 548 548 549 549 /* start the pipeline */ 550 - ret = media_pipeline_start(&chan->video.entity, pipe); 550 + ret = video_device_pipeline_start(&chan->video, pipe); 551 551 if (ret < 0) 552 552 goto error_pipeline_start; 553 553 ··· 595 595 error_kthread_start: 596 596 tegra_channel_set_stream(chan, false); 597 597 error_set_stream: 598 - media_pipeline_stop(&chan->video.entity); 598 + video_device_pipeline_stop(&chan->video); 599 599 error_pipeline_start: 600 600 tegra_channel_release_buffers(chan, VB2_BUF_STATE_QUEUED); 601 601 return ret; ··· 617 617 618 618 tegra_channel_release_buffers(chan, VB2_BUF_STATE_ERROR); 619 619 tegra_channel_set_stream(chan, false); 620 - media_pipeline_stop(&chan->video.entity); 620 + video_device_pipeline_stop(&chan->video); 621 621 } 622 622 623 623 /*
+1
include/media/i2c/ir-kbd-i2c.h
··· 35 35 IR_KBD_GET_KEY_PIXELVIEW, 36 36 IR_KBD_GET_KEY_HAUP, 37 37 IR_KBD_GET_KEY_KNC1, 38 + IR_KBD_GET_KEY_GENIATECH, 38 39 IR_KBD_GET_KEY_FUSIONHDTV, 39 40 IR_KBD_GET_KEY_HAUP_XVR, 40 41 IR_KBD_GET_KEY_AVERMEDIA_CARDBUS,
-15
include/media/media-device.h
··· 192 192 #define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 193 193 194 194 /** 195 - * media_entity_enum_init - Initialise an entity enumeration 196 - * 197 - * @ent_enum: Entity enumeration to be initialised 198 - * @mdev: The related media device 199 - * 200 - * Return: zero on success or a negative error code. 201 - */ 202 - static inline __must_check int media_entity_enum_init( 203 - struct media_entity_enum *ent_enum, struct media_device *mdev) 204 - { 205 - return __media_entity_enum_init(ent_enum, 206 - mdev->entity_internal_idx_max + 1); 207 - } 208 - 209 - /** 210 195 * media_device_init() - Initializes a media device element 211 196 * 212 197 * @mdev: pointer to struct &media_device
+142 -27
include/media/media-entity.h
··· 17 17 #include <linux/fwnode.h> 18 18 #include <linux/list.h> 19 19 #include <linux/media.h> 20 + #include <linux/minmax.h> 20 21 #include <linux/types.h> 21 22 22 23 /* Enums used internally at the media controller to represent graphs */ ··· 100 99 /** 101 100 * struct media_pipeline - Media pipeline related information 102 101 * 103 - * @streaming_count: Streaming start count - streaming stop count 104 - * @graph: Media graph walk during pipeline start / stop 102 + * @allocated: Media pipeline allocated and freed by the framework 103 + * @mdev: The media device the pipeline is part of 104 + * @pads: List of media_pipeline_pad 105 + * @start_count: Media pipeline start - stop count 105 106 */ 106 107 struct media_pipeline { 107 - int streaming_count; 108 - struct media_graph graph; 108 + bool allocated; 109 + struct media_device *mdev; 110 + struct list_head pads; 111 + int start_count; 112 + }; 113 + 114 + /** 115 + * struct media_pipeline_pad - A pad part of a media pipeline 116 + * 117 + * @list: Entry in the media_pad pads list 118 + * @pipe: The media_pipeline that the pad is part of 119 + * @pad: The media pad 120 + * 121 + * This structure associate a pad with a media pipeline. Instances of 122 + * media_pipeline_pad are created by media_pipeline_start() when it builds the 123 + * pipeline, and stored in the &media_pad.pads list. media_pipeline_stop() 124 + * removes the entries from the list and deletes them. 125 + */ 126 + struct media_pipeline_pad { 127 + struct list_head list; 128 + struct media_pipeline *pipe; 129 + struct media_pad *pad; 109 130 }; 110 131 111 132 /** ··· 209 186 * @flags: Pad flags, as defined in 210 187 * :ref:`include/uapi/linux/media.h <media_header>` 211 188 * (seek for ``MEDIA_PAD_FL_*``) 189 + * @pipe: Pipeline this pad belongs to. Use media_entity_pipeline() to 190 + * access this field. 212 191 */ 213 192 struct media_pad { 214 193 struct media_gobj graph_obj; /* must be first field in struct */ ··· 218 193 u16 index; 219 194 enum media_pad_signal_type sig_type; 220 195 unsigned long flags; 196 + 197 + /* 198 + * The fields below are private, and should only be accessed via 199 + * appropriate functions. 200 + */ 201 + struct media_pipeline *pipe; 221 202 }; 222 203 223 204 /** ··· 237 206 * @link_validate: Return whether a link is valid from the entity point of 238 207 * view. The media_pipeline_start() function 239 208 * validates all links by calling this operation. Optional. 209 + * @has_pad_interdep: Return whether a two pads inside the entity are 210 + * interdependent. If two pads are interdependent they are 211 + * part of the same pipeline and enabling one of the pads 212 + * means that the other pad will become "locked" and 213 + * doesn't allow configuration changes. pad0 and pad1 are 214 + * guaranteed to not both be sinks or sources. 215 + * Optional: If the operation isn't implemented all pads 216 + * will be considered as interdependent. 240 217 * 241 218 * .. note:: 242 219 * ··· 258 219 const struct media_pad *local, 259 220 const struct media_pad *remote, u32 flags); 260 221 int (*link_validate)(struct media_link *link); 222 + bool (*has_pad_interdep)(struct media_entity *entity, unsigned int pad0, 223 + unsigned int pad1); 261 224 }; 262 225 263 226 /** ··· 310 269 * @links: List of data links. 311 270 * @ops: Entity operations. 312 271 * @use_count: Use count for the entity. 313 - * @pipe: Pipeline this entity belongs to. 314 272 * @info: Union with devnode information. Kept just for backward 315 273 * compatibility. 316 274 * @info.dev: Contains device major and minor info. ··· 345 305 346 306 int use_count; 347 307 348 - struct media_pipeline *pipe; 349 - 350 308 union { 351 309 struct { 352 310 u32 major; ··· 352 314 } dev; 353 315 } info; 354 316 }; 317 + 318 + /** 319 + * media_entity_for_each_pad - Iterate on all pads in an entity 320 + * @entity: The entity the pads belong to 321 + * @iter: The iterator pad 322 + * 323 + * Iterate on all pads in a media entity. 324 + */ 325 + #define media_entity_for_each_pad(entity, iter) \ 326 + for (iter = (entity)->pads; \ 327 + iter < &(entity)->pads[(entity)->num_pads]; \ 328 + ++iter) 355 329 356 330 /** 357 331 * struct media_interface - A media interface graph object. ··· 476 426 } 477 427 478 428 /** 479 - * __media_entity_enum_init - Initialise an entity enumeration 429 + * media_entity_enum_init - Initialise an entity enumeration 480 430 * 481 431 * @ent_enum: Entity enumeration to be initialised 482 - * @idx_max: Maximum number of entities in the enumeration 432 + * @mdev: The related media device 483 433 * 484 - * Return: Returns zero on success or a negative error code. 434 + * Return: zero on success or a negative error code. 485 435 */ 486 - __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, 487 - int idx_max); 436 + __must_check int media_entity_enum_init(struct media_entity_enum *ent_enum, 437 + struct media_device *mdev); 488 438 489 439 /** 490 440 * media_entity_enum_cleanup - Release resources of an entity enumeration ··· 974 924 } 975 925 976 926 /** 927 + * media_pad_is_streaming - Test if a pad is part of a streaming pipeline 928 + * @pad: The pad 929 + * 930 + * Return: True if the pad is part of a pipeline started with the 931 + * media_pipeline_start() function, false otherwise. 932 + */ 933 + static inline bool media_pad_is_streaming(const struct media_pad *pad) 934 + { 935 + return pad->pipe; 936 + } 937 + 938 + /** 977 939 * media_entity_is_streaming - Test if an entity is part of a streaming pipeline 978 940 * @entity: The entity 979 941 * ··· 994 932 */ 995 933 static inline bool media_entity_is_streaming(const struct media_entity *entity) 996 934 { 997 - return entity->pipe; 935 + struct media_pad *pad; 936 + 937 + media_entity_for_each_pad(entity, pad) { 938 + if (media_pad_is_streaming(pad)) 939 + return true; 940 + } 941 + 942 + return false; 998 943 } 944 + 945 + /** 946 + * media_entity_pipeline - Get the media pipeline an entity is part of 947 + * @entity: The entity 948 + * 949 + * DEPRECATED: use media_pad_pipeline() instead. 950 + * 951 + * This function returns the media pipeline that an entity has been associated 952 + * with when constructing the pipeline with media_pipeline_start(). The pointer 953 + * remains valid until media_pipeline_stop() is called. 954 + * 955 + * In general, entities can be part of multiple pipelines, when carrying 956 + * multiple streams (either on different pads, or on the same pad using 957 + * multiplexed streams). This function is to be used only for entities that 958 + * do not support multiple pipelines. 959 + * 960 + * Return: The media_pipeline the entity is part of, or NULL if the entity is 961 + * not part of any pipeline. 962 + */ 963 + struct media_pipeline *media_entity_pipeline(struct media_entity *entity); 964 + 965 + /** 966 + * media_pad_pipeline - Get the media pipeline a pad is part of 967 + * @pad: The pad 968 + * 969 + * This function returns the media pipeline that a pad has been associated 970 + * with when constructing the pipeline with media_pipeline_start(). The pointer 971 + * remains valid until media_pipeline_stop() is called. 972 + * 973 + * Return: The media_pipeline the pad is part of, or NULL if the pad is 974 + * not part of any pipeline. 975 + */ 976 + struct media_pipeline *media_pad_pipeline(struct media_pad *pad); 999 977 1000 978 /** 1001 979 * media_entity_get_fwnode_pad - Get pad number from fwnode ··· 1115 1013 1116 1014 /** 1117 1015 * media_pipeline_start - Mark a pipeline as streaming 1118 - * @entity: Starting entity 1119 - * @pipe: Media pipeline to be assigned to all entities in the pipeline. 1016 + * @pad: Starting pad 1017 + * @pipe: Media pipeline to be assigned to all pads in the pipeline. 1120 1018 * 1121 - * Mark all entities connected to a given entity through enabled links, either 1019 + * Mark all pads connected to a given pad through enabled links, either 1122 1020 * directly or indirectly, as streaming. The given pipeline object is assigned 1123 - * to every entity in the pipeline and stored in the media_entity pipe field. 1021 + * to every pad in the pipeline and stored in the media_pad pipe field. 1124 1022 * 1125 1023 * Calls to this function can be nested, in which case the same number of 1126 1024 * media_pipeline_stop() calls will be required to stop streaming. The 1127 1025 * pipeline pointer must be identical for all nested calls to 1128 1026 * media_pipeline_start(). 1129 1027 */ 1130 - __must_check int media_pipeline_start(struct media_entity *entity, 1028 + __must_check int media_pipeline_start(struct media_pad *pad, 1131 1029 struct media_pipeline *pipe); 1132 1030 /** 1133 1031 * __media_pipeline_start - Mark a pipeline as streaming 1134 1032 * 1135 - * @entity: Starting entity 1136 - * @pipe: Media pipeline to be assigned to all entities in the pipeline. 1033 + * @pad: Starting pad 1034 + * @pipe: Media pipeline to be assigned to all pads in the pipeline. 1137 1035 * 1138 1036 * ..note:: This is the non-locking version of media_pipeline_start() 1139 1037 */ 1140 - __must_check int __media_pipeline_start(struct media_entity *entity, 1038 + __must_check int __media_pipeline_start(struct media_pad *pad, 1141 1039 struct media_pipeline *pipe); 1142 1040 1143 1041 /** 1144 1042 * media_pipeline_stop - Mark a pipeline as not streaming 1145 - * @entity: Starting entity 1043 + * @pad: Starting pad 1146 1044 * 1147 - * Mark all entities connected to a given entity through enabled links, either 1148 - * directly or indirectly, as not streaming. The media_entity pipe field is 1045 + * Mark all pads connected to a given pads through enabled links, either 1046 + * directly or indirectly, as not streaming. The media_pad pipe field is 1149 1047 * reset to %NULL. 1150 1048 * 1151 1049 * If multiple calls to media_pipeline_start() have been made, the same 1152 1050 * number of calls to this function are required to mark the pipeline as not 1153 1051 * streaming. 1154 1052 */ 1155 - void media_pipeline_stop(struct media_entity *entity); 1053 + void media_pipeline_stop(struct media_pad *pad); 1156 1054 1157 1055 /** 1158 1056 * __media_pipeline_stop - Mark a pipeline as not streaming 1159 1057 * 1160 - * @entity: Starting entity 1058 + * @pad: Starting pad 1161 1059 * 1162 1060 * .. note:: This is the non-locking version of media_pipeline_stop() 1163 1061 */ 1164 - void __media_pipeline_stop(struct media_entity *entity); 1062 + void __media_pipeline_stop(struct media_pad *pad); 1063 + 1064 + /** 1065 + * media_pipeline_alloc_start - Mark a pipeline as streaming 1066 + * @pad: Starting pad 1067 + * 1068 + * media_pipeline_alloc_start() is similar to media_pipeline_start() but instead 1069 + * of working on a given pipeline the function will use an existing pipeline if 1070 + * the pad is already part of a pipeline, or allocate a new pipeline. 1071 + * 1072 + * Calls to media_pipeline_alloc_start() must be matched with 1073 + * media_pipeline_stop(). 1074 + */ 1075 + __must_check int media_pipeline_alloc_start(struct media_pad *pad); 1165 1076 1166 1077 /** 1167 1078 * media_devnode_create() - creates and initializes a device node interface
+2 -1
include/media/v4l2-common.h
··· 175 175 * 176 176 * @sd: pointer to &struct v4l2_subdev 177 177 * @client: pointer to struct i2c_client 178 - * @devname: the name of the device; if NULL, the I²C device's name will be used 178 + * @devname: the name of the device; if NULL, the I²C device drivers's name 179 + * will be used 179 180 * @postfix: sub-device specific string to put right after the I²C device name; 180 181 * may be NULL 181 182 */
+11 -17
include/media/v4l2-ctrls.h
··· 121 121 * struct v4l2_ctrl_type_ops - The control type operations that the driver 122 122 * has to provide. 123 123 * 124 - * @equal: return true if both values are equal. 125 - * @init: initialize the value. 124 + * @equal: return true if all ctrl->elems array elements are equal. 125 + * @init: initialize the value for array elements from from_idx to ctrl->elems. 126 126 * @log: log the value. 127 - * @validate: validate the value. Return 0 on success and a negative value 128 - * otherwise. 127 + * @validate: validate the value for ctrl->new_elems array elements. 128 + * Return 0 on success and a negative value otherwise. 129 129 */ 130 130 struct v4l2_ctrl_type_ops { 131 - bool (*equal)(const struct v4l2_ctrl *ctrl, u32 elems, 132 - union v4l2_ctrl_ptr ptr1, 133 - union v4l2_ctrl_ptr ptr2); 134 - void (*init)(const struct v4l2_ctrl *ctrl, u32 from_idx, u32 tot_elems, 131 + bool (*equal)(const struct v4l2_ctrl *ctrl, 132 + union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2); 133 + void (*init)(const struct v4l2_ctrl *ctrl, u32 from_idx, 135 134 union v4l2_ctrl_ptr ptr); 136 135 void (*log)(const struct v4l2_ctrl *ctrl); 137 - int (*validate)(const struct v4l2_ctrl *ctrl, u32 elems, 138 - union v4l2_ctrl_ptr ptr); 136 + int (*validate)(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr); 139 137 }; 140 138 141 139 /** ··· 1541 1543 * v4l2_ctrl_type_op_equal - Default v4l2_ctrl_type_ops equal callback. 1542 1544 * 1543 1545 * @ctrl: The v4l2_ctrl pointer. 1544 - * @elems: The number of elements to compare. 1545 1546 * @ptr1: A v4l2 control value. 1546 1547 * @ptr2: A v4l2 control value. 1547 1548 * 1548 1549 * Return: true if values are equal, otherwise false. 1549 1550 */ 1550 - bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, u32 elems, 1551 + bool v4l2_ctrl_type_op_equal(const struct v4l2_ctrl *ctrl, 1551 1552 union v4l2_ctrl_ptr ptr1, union v4l2_ctrl_ptr ptr2); 1552 1553 1553 1554 /** ··· 1554 1557 * 1555 1558 * @ctrl: The v4l2_ctrl pointer. 1556 1559 * @from_idx: Starting element index. 1557 - * @elems: The number of elements to initialize. 1558 1560 * @ptr: The v4l2 control value. 1559 1561 * 1560 1562 * Return: void 1561 1563 */ 1562 1564 void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, u32 from_idx, 1563 - u32 elems, union v4l2_ctrl_ptr ptr); 1565 + union v4l2_ctrl_ptr ptr); 1564 1566 1565 1567 /** 1566 1568 * v4l2_ctrl_type_op_log - Default v4l2_ctrl_type_ops log callback. ··· 1574 1578 * v4l2_ctrl_type_op_validate - Default v4l2_ctrl_type_ops validate callback. 1575 1579 * 1576 1580 * @ctrl: The v4l2_ctrl pointer. 1577 - * @elems: The number of elements in the control. 1578 1581 * @ptr: The v4l2 control value. 1579 1582 * 1580 1583 * Return: 0 on success, a negative error code on failure. 1581 1584 */ 1582 - int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, u32 elems, 1583 - union v4l2_ctrl_ptr ptr); 1585 + int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr ptr); 1584 1586 1585 1587 #endif
+102
include/media/v4l2-dev.h
··· 539 539 return test_bit(V4L2_FL_REGISTERED, &vdev->flags); 540 540 } 541 541 542 + #if defined(CONFIG_MEDIA_CONTROLLER) 543 + 544 + /** 545 + * video_device_pipeline_start - Mark a pipeline as streaming 546 + * @vdev: Starting video device 547 + * @pipe: Media pipeline to be assigned to all entities in the pipeline. 548 + * 549 + * Mark all entities connected to a given video device through enabled links, 550 + * either directly or indirectly, as streaming. The given pipeline object is 551 + * assigned to every pad in the pipeline and stored in the media_pad pipe 552 + * field. 553 + * 554 + * Calls to this function can be nested, in which case the same number of 555 + * video_device_pipeline_stop() calls will be required to stop streaming. The 556 + * pipeline pointer must be identical for all nested calls to 557 + * video_device_pipeline_start(). 558 + * 559 + * The video device must contain a single pad. 560 + * 561 + * This is a convenience wrapper around media_pipeline_start(). 562 + */ 563 + __must_check int video_device_pipeline_start(struct video_device *vdev, 564 + struct media_pipeline *pipe); 565 + 566 + /** 567 + * __video_device_pipeline_start - Mark a pipeline as streaming 568 + * @vdev: Starting video device 569 + * @pipe: Media pipeline to be assigned to all entities in the pipeline. 570 + * 571 + * ..note:: This is the non-locking version of video_device_pipeline_start() 572 + * 573 + * The video device must contain a single pad. 574 + * 575 + * This is a convenience wrapper around __media_pipeline_start(). 576 + */ 577 + __must_check int __video_device_pipeline_start(struct video_device *vdev, 578 + struct media_pipeline *pipe); 579 + 580 + /** 581 + * video_device_pipeline_stop - Mark a pipeline as not streaming 582 + * @vdev: Starting video device 583 + * 584 + * Mark all entities connected to a given video device through enabled links, 585 + * either directly or indirectly, as not streaming. The media_pad pipe field 586 + * is reset to %NULL. 587 + * 588 + * If multiple calls to media_pipeline_start() have been made, the same 589 + * number of calls to this function are required to mark the pipeline as not 590 + * streaming. 591 + * 592 + * The video device must contain a single pad. 593 + * 594 + * This is a convenience wrapper around media_pipeline_stop(). 595 + */ 596 + void video_device_pipeline_stop(struct video_device *vdev); 597 + 598 + /** 599 + * __video_device_pipeline_stop - Mark a pipeline as not streaming 600 + * @vdev: Starting video device 601 + * 602 + * .. note:: This is the non-locking version of media_pipeline_stop() 603 + * 604 + * The video device must contain a single pad. 605 + * 606 + * This is a convenience wrapper around __media_pipeline_stop(). 607 + */ 608 + void __video_device_pipeline_stop(struct video_device *vdev); 609 + 610 + /** 611 + * video_device_pipeline_alloc_start - Mark a pipeline as streaming 612 + * @vdev: Starting video device 613 + * 614 + * video_device_pipeline_alloc_start() is similar to video_device_pipeline_start() 615 + * but instead of working on a given pipeline the function will use an 616 + * existing pipeline if the video device is already part of a pipeline, or 617 + * allocate a new pipeline. 618 + * 619 + * Calls to video_device_pipeline_alloc_start() must be matched with 620 + * video_device_pipeline_stop(). 621 + */ 622 + __must_check int video_device_pipeline_alloc_start(struct video_device *vdev); 623 + 624 + /** 625 + * video_device_pipeline - Get the media pipeline a video device is part of 626 + * @vdev: The video device 627 + * 628 + * This function returns the media pipeline that a video device has been 629 + * associated with when constructing the pipeline with 630 + * video_device_pipeline_start(). The pointer remains valid until 631 + * video_device_pipeline_stop() is called. 632 + * 633 + * Return: The media_pipeline the video device is part of, or NULL if the video 634 + * device is not part of any pipeline. 635 + * 636 + * The video device must contain a single pad. 637 + * 638 + * This is a convenience wrapper around media_entity_pipeline(). 639 + */ 640 + struct media_pipeline *video_device_pipeline(struct video_device *vdev); 641 + 642 + #endif /* CONFIG_MEDIA_CONTROLLER */ 643 + 542 644 #endif /* _V4L2_DEV_H */
-4
include/media/v4l2-fwnode.h
··· 45 45 */ 46 46 struct v4l2_fwnode_endpoint { 47 47 struct fwnode_endpoint base; 48 - /* 49 - * Fields below this line will be zeroed by 50 - * v4l2_fwnode_endpoint_parse() 51 - */ 52 48 enum v4l2_mbus_type bus_type; 53 49 struct { 54 50 struct v4l2_mbus_config_parallel parallel;
+11 -1
include/media/v4l2-subdev.h
··· 358 358 } bus; 359 359 }; 360 360 361 - #define V4L2_FRAME_DESC_ENTRY_MAX 4 361 + /* 362 + * If this number is too small, it should be dropped altogether and the 363 + * API switched to a dynamic number of frame descriptor entries. 364 + */ 365 + #define V4L2_FRAME_DESC_ENTRY_MAX 8 362 366 363 367 /** 364 368 * enum v4l2_mbus_frame_desc_type - media bus frame description type ··· 1050 1046 struct v4l2_subdev_state *state, 1051 1047 unsigned int pad) 1052 1048 { 1049 + if (WARN_ON(!state)) 1050 + return NULL; 1053 1051 if (WARN_ON(pad >= sd->entity.num_pads)) 1054 1052 pad = 0; 1055 1053 return &state->pads[pad].try_fmt; ··· 1070 1064 struct v4l2_subdev_state *state, 1071 1065 unsigned int pad) 1072 1066 { 1067 + if (WARN_ON(!state)) 1068 + return NULL; 1073 1069 if (WARN_ON(pad >= sd->entity.num_pads)) 1074 1070 pad = 0; 1075 1071 return &state->pads[pad].try_crop; ··· 1090 1082 struct v4l2_subdev_state *state, 1091 1083 unsigned int pad) 1092 1084 { 1085 + if (WARN_ON(!state)) 1086 + return NULL; 1093 1087 if (WARN_ON(pad >= sd->entity.num_pads)) 1094 1088 pad = 0; 1095 1089 return &state->pads[pad].try_compose;
+14
include/uapi/linux/cec-funcs.h
··· 1568 1568 } 1569 1569 } 1570 1570 1571 + static inline void cec_msg_set_audio_volume_level(struct cec_msg *msg, 1572 + __u8 audio_volume_level) 1573 + { 1574 + msg->len = 3; 1575 + msg->msg[1] = CEC_MSG_SET_AUDIO_VOLUME_LEVEL; 1576 + msg->msg[2] = audio_volume_level; 1577 + } 1578 + 1579 + static inline void cec_ops_set_audio_volume_level(const struct cec_msg *msg, 1580 + __u8 *audio_volume_level) 1581 + { 1582 + *audio_volume_level = msg->msg[2]; 1583 + } 1584 + 1571 1585 1572 1586 /* Audio Rate Control Feature */ 1573 1587 static inline void cec_msg_set_audio_rate(struct cec_msg *msg,
+2
include/uapi/linux/cec.h
··· 768 768 #define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08 769 769 #define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04 770 770 #define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02 771 + #define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_VOLUME_LEVEL 0x01 771 772 772 773 #define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */ 773 774 ··· 1060 1059 #define CEC_OP_AUD_FMT_ID_CEA861 0 1061 1060 #define CEC_OP_AUD_FMT_ID_CEA861_CXT 1 1062 1061 1062 + #define CEC_MSG_SET_AUDIO_VOLUME_LEVEL 0x73 1063 1063 1064 1064 /* Audio Rate Control Feature */ 1065 1065 #define CEC_MSG_SET_AUDIO_RATE 0x9a
+61 -16
include/uapi/linux/rkisp1-config.h
··· 117 117 /* 118 118 * Defect Pixel Cluster Correction 119 119 */ 120 - #define RKISP1_CIF_ISP_DPCC_METHODS_MAX 3 120 + #define RKISP1_CIF_ISP_DPCC_METHODS_MAX 3 121 + 122 + #define RKISP1_CIF_ISP_DPCC_MODE_STAGE1_ENABLE (1U << 2) 123 + 124 + #define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_G_CENTER (1U << 0) 125 + #define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_INCL_RB_CENTER (1U << 1) 126 + #define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_G_3X3 (1U << 2) 127 + #define RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_STAGE1_RB_3X3 (1U << 3) 128 + 129 + /* 0-2 for sets 1-3 */ 130 + #define RKISP1_CIF_ISP_DPCC_SET_USE_STAGE1_USE_SET(n) ((n) << 0) 131 + #define RKISP1_CIF_ISP_DPCC_SET_USE_STAGE1_USE_FIX_SET (1U << 3) 132 + 133 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE (1U << 0) 134 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE (1U << 1) 135 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE (1U << 2) 136 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE (1U << 3) 137 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE (1U << 4) 138 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE (1U << 8) 139 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE (1U << 9) 140 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE (1U << 10) 141 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE (1U << 11) 142 + #define RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE (1U << 12) 143 + 144 + #define RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(v) ((v) << 0) 145 + #define RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(v) ((v) << 8) 146 + #define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(v) ((v) << 0) 147 + #define RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(v) ((v) << 8) 148 + #define RKISP1_CIF_ISP_DPCC_PG_FAC_G(v) ((v) << 0) 149 + #define RKISP1_CIF_ISP_DPCC_PG_FAC_RB(v) ((v) << 8) 150 + #define RKISP1_CIF_ISP_DPCC_RND_THRESH_G(v) ((v) << 0) 151 + #define RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(v) ((v) << 8) 152 + #define RKISP1_CIF_ISP_DPCC_RG_FAC_G(v) ((v) << 0) 153 + #define RKISP1_CIF_ISP_DPCC_RG_FAC_RB(v) ((v) << 8) 154 + 155 + #define RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(n, v) ((v) << ((n) * 4)) 156 + #define RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(n, v) ((v) << ((n) * 4 + 2)) 157 + 158 + #define RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(n, v) ((v) << ((n) * 4)) 159 + #define RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(n, v) ((v) << ((n) * 4 + 2)) 121 160 122 161 /* 123 162 * Denoising pre filter ··· 288 249 }; 289 250 290 251 /** 291 - * struct rkisp1_cif_isp_dpcc_methods_config - Methods Configuration used by DPCC 252 + * struct rkisp1_cif_isp_dpcc_methods_config - DPCC methods set configuration 292 253 * 293 - * Methods Configuration used by Defect Pixel Cluster Correction 254 + * This structure stores the configuration of one set of methods for the DPCC 255 + * algorithm. Multiple methods can be selected in each set (independently for 256 + * the Green and Red/Blue components) through the @method field, the result is 257 + * the logical AND of all enabled methods. The remaining fields set thresholds 258 + * and factors for each method. 294 259 * 295 - * @method: Method enable bits 296 - * @line_thresh: Line threshold 297 - * @line_mad_fac: Line MAD factor 298 - * @pg_fac: Peak gradient factor 299 - * @rnd_thresh: Rank Neighbor Difference threshold 300 - * @rg_fac: Rank gradient factor 260 + * @method: Method enable bits (RKISP1_CIF_ISP_DPCC_METHODS_SET_*) 261 + * @line_thresh: Line threshold (RKISP1_CIF_ISP_DPCC_LINE_THRESH_*) 262 + * @line_mad_fac: Line Mean Absolute Difference factor (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_*) 263 + * @pg_fac: Peak gradient factor (RKISP1_CIF_ISP_DPCC_PG_FAC_*) 264 + * @rnd_thresh: Rank Neighbor Difference threshold (RKISP1_CIF_ISP_DPCC_RND_THRESH_*) 265 + * @rg_fac: Rank gradient factor (RKISP1_CIF_ISP_DPCC_RG_FAC_*) 301 266 */ 302 267 struct rkisp1_cif_isp_dpcc_methods_config { 303 268 __u32 method; ··· 315 272 /** 316 273 * struct rkisp1_cif_isp_dpcc_config - Configuration used by DPCC 317 274 * 318 - * Configuration used by Defect Pixel Cluster Correction 275 + * Configuration used by Defect Pixel Cluster Correction. Three sets of methods 276 + * can be configured and selected through the @set_use field. The result is the 277 + * logical OR of all enabled sets. 319 278 * 320 - * @mode: dpcc output mode 321 - * @output_mode: whether use hard coded methods 322 - * @set_use: stage1 methods set 323 - * @methods: methods config 324 - * @ro_limits: rank order limits 325 - * @rnd_offs: differential rank offsets for rank neighbor difference 279 + * @mode: DPCC mode (RKISP1_CIF_ISP_DPCC_MODE_*) 280 + * @output_mode: Interpolation output mode (RKISP1_CIF_ISP_DPCC_OUTPUT_MODE_*) 281 + * @set_use: Methods sets selection (RKISP1_CIF_ISP_DPCC_SET_USE_*) 282 + * @methods: Methods sets configuration 283 + * @ro_limits: Rank order limits (RKISP1_CIF_ISP_DPCC_RO_LIMITS_*) 284 + * @rnd_offs: Differential rank offsets for rank neighbor difference (RKISP1_CIF_ISP_DPCC_RND_OFFS_*) 326 285 */ 327 286 struct rkisp1_cif_isp_dpcc_config { 328 287 __u32 mode;