Pull media fixes from Mauro Carvalho Chehab: "Media regression fixes: - serial_ir: fix a Kernel crash during boot on Kernel 4.11-rc1, due to an IRQ code called too early - other IR regression fixes at lirc and at the raw IR decoding - a deadlock fix at the RC nuvoton driver - fix another issue with DMA on stack at dw2102 driver There's an extra patch there that change a driver interface for the SoC VSP1 driver, with is shared between the DRM and V4L2 driver. The patch itself is trivial, and was acked by David Arlie" * tag 'media/v4.11-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: [media] v4l: vsp1: Adapt vsp1_du_setup_lif() interface to use a structure [media] dw2102: don't do DMA on stack [media] rc: protocol is not set on register for raw IR devices [media] rc: raw decoder for keymap protocol is not loaded on register [media] rc: nuvoton: fix deadlock in nvt_write_wakeup_codes [media] lirc: fix dead lock between open and wakeup_filter [media] serial_ir: ensure we're ready to receive interrupts
Unified · Split
| @@ -32,6 +32,10 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) · 31 unmodified lines | ||
| 32 | 32 | { |
| 33 | 33 | const struct drm_display_mode *mode = &crtc->crtc.state->adjusted_mode; |
| 34 | 34 | struct rcar_du_device *rcdu = crtc->group->dev; |
| 35 | + struct vsp1_du_lif_config cfg = { | |
| 36 | + .width = mode->hdisplay, | |
| 37 | + .height = mode->vdisplay, | |
| 38 | + }; | |
| 35 | 39 | struct rcar_du_plane_state state = { |
| 36 | 40 | .state = { |
| 37 | 41 | .crtc = &crtc->crtc, |
| @@ -66,12 +70,12 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc) · 28 unmodified lines | ||
| 66 | 70 | */ |
| 67 | 71 | crtc->group->need_restart = true; |
| 68 | 72 | |
| 69 | − vsp1_du_setup_lif(crtc->vsp->vsp, mode->hdisplay, mode->vdisplay); | |
| 73 | + vsp1_du_setup_lif(crtc->vsp->vsp, &cfg); | |
| 70 | 74 | } |
| 71 | 75 | |
| 72 | 76 | void rcar_du_vsp_disable(struct rcar_du_crtc *crtc) |
| 73 | 77 | { |
| 74 | − vsp1_du_setup_lif(crtc->vsp->vsp, 0, 0); | |
| 78 | + vsp1_du_setup_lif(crtc->vsp->vsp, NULL); | |
| 75 | 79 | } |
| 76 | 80 | |
| 77 | 81 | void rcar_du_vsp_atomic_begin(struct rcar_du_crtc *crtc) |
| @@ -54,12 +54,11 @@ EXPORT_SYMBOL_GPL(vsp1_du_init); · 53 unmodified lines | ||
| 54 | 54 | /** |
| 55 | 55 | * vsp1_du_setup_lif - Setup the output part of the VSP pipeline |
| 56 | 56 | * @dev: the VSP device |
| 57 | − * @width: output frame width in pixels | |
| 58 | − * @height: output frame height in pixels | |
| 57 | + * @cfg: the LIF configuration | |
| 59 | 58 | * |
| 60 | − * Configure the output part of VSP DRM pipeline for the given frame @width and | |
| 61 | − * @height. This sets up formats on the BRU source pad, the WPF0 sink and source | |
| 62 | − * pads, and the LIF sink pad. | |
| 59 | + * Configure the output part of VSP DRM pipeline for the given frame @cfg.width | |
| 60 | + * and @cfg.height. This sets up formats on the BRU source pad, the WPF0 sink | |
| 61 | + * and source pads, and the LIF sink pad. | |
| 63 | 62 | * |
| 64 | 63 | * As the media bus code on the BRU source pad is conditioned by the |
| 65 | 64 | * configuration of the BRU sink 0 pad, we also set up the formats on all BRU |
| @@ -69,8 +68,7 @@ EXPORT_SYMBOL_GPL(vsp1_du_init); · 3 unmodified lines | ||
| 69 | 68 | * |
| 70 | 69 | * Return 0 on success or a negative error code on failure. |
| 71 | 70 | */ |
| 72 | −int vsp1_du_setup_lif(struct device *dev, unsigned int width, | |
| 73 | − unsigned int height) | |
| 71 | +int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg) | |
| 74 | 72 | { |
| 75 | 73 | struct vsp1_device *vsp1 = dev_get_drvdata(dev); |
| 76 | 74 | struct vsp1_pipeline *pipe = &vsp1->drm->pipe; |
| @@ -79,11 +77,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, · 2 unmodified lines | ||
| 79 | 77 | unsigned int i; |
| 80 | 78 | int ret; |
| 81 | 79 | |
| 82 | − dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n", | |
| 83 | − __func__, width, height); | |
| 84 | − | |
| 85 | − if (width == 0 || height == 0) { | |
| 86 | − /* Zero width or height means the CRTC is being disabled, stop | |
| 80 | + if (!cfg) { | |
| 81 | + /* NULL configuration means the CRTC is being disabled, stop | |
| 87 | 82 | * the pipeline and turn the light off. |
| 88 | 83 | */ |
| 89 | 84 | ret = vsp1_pipeline_stop(pipe); |
| @@ -108,6 +103,9 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, · 18 unmodified lines | ||
| 108 | 103 | return 0; |
| 109 | 104 | } |
| 110 | 105 | |
| 106 | + dev_dbg(vsp1->dev, "%s: configuring LIF with format %ux%u\n", | |
| 107 | + __func__, cfg->width, cfg->height); | |
| 108 | + | |
| 111 | 109 | /* Configure the format at the BRU sinks and propagate it through the |
| 112 | 110 | * pipeline. |
| 113 | 111 | */ |
| @@ -117,8 +115,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, · 3 unmodified lines | ||
| 117 | 115 | for (i = 0; i < bru->entity.source_pad; ++i) { |
| 118 | 116 | format.pad = i; |
| 119 | 117 | |
| 120 | − format.format.width = width; | |
| 121 | − format.format.height = height; | |
| 118 | + format.format.width = cfg->width; | |
| 119 | + format.format.height = cfg->height; | |
| 122 | 120 | format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; |
| 123 | 121 | format.format.field = V4L2_FIELD_NONE; |
| 124 | 122 | |
| @@ -133,8 +131,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, · 8 unmodified lines | ||
| 133 | 131 | } |
| 134 | 132 | |
| 135 | 133 | format.pad = bru->entity.source_pad; |
| 136 | − format.format.width = width; | |
| 137 | − format.format.height = height; | |
| 134 | + format.format.width = cfg->width; | |
| 135 | + format.format.height = cfg->height; | |
| 138 | 136 | format.format.code = MEDIA_BUS_FMT_ARGB8888_1X32; |
| 139 | 137 | format.format.field = V4L2_FIELD_NONE; |
| 140 | 138 | |
| @@ -180,7 +178,8 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, · 39 unmodified lines | ||
| 180 | 178 | /* Verify that the format at the output of the pipeline matches the |
| 181 | 179 | * requested frame size and media bus code. |
| 182 | 180 | */ |
| 183 | − if (format.format.width != width || format.format.height != height || | |
| 181 | + if (format.format.width != cfg->width || | |
| 182 | + format.format.height != cfg->height || | |
| 184 | 183 | format.format.code != MEDIA_BUS_FMT_ARGB8888_1X32) { |
| 185 | 184 | dev_dbg(vsp1->dev, "%s: format mismatch\n", __func__); |
| 186 | 185 | return -EPIPE; |
| @@ -436,6 +436,8 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) · 435 unmodified lines | ||
| 436 | 436 | return -ERESTARTSYS; |
| 437 | 437 | |
| 438 | 438 | ir = irctls[iminor(inode)]; |
| 439 | + mutex_unlock(&lirc_dev_lock); | |
| 440 | + | |
| 439 | 441 | if (!ir) { |
| 440 | 442 | retval = -ENODEV; |
| 441 | 443 | goto error; |
| @@ -476,8 +478,6 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) · 34 unmodified lines | ||
| 476 | 478 | } |
| 477 | 479 | |
| 478 | 480 | error: |
| 479 | − mutex_unlock(&lirc_dev_lock); | |
| 480 | − | |
| 481 | 481 | nonseekable_open(inode, file); |
| 482 | 482 | |
| 483 | 483 | return retval; |
| @@ -176,12 +176,13 @@ static void nvt_write_wakeup_codes(struct rc_dev *dev, · 175 unmodified lines | ||
| 176 | 176 | { |
| 177 | 177 | u8 tolerance, config; |
| 178 | 178 | struct nvt_dev *nvt = dev->priv; |
| 179 | + unsigned long flags; | |
| 179 | 180 | int i; |
| 180 | 181 | |
| 181 | 182 | /* hardcode the tolerance to 10% */ |
| 182 | 183 | tolerance = DIV_ROUND_UP(count, 10); |
| 183 | 184 | |
| 184 | − spin_lock(&nvt->lock); | |
| 185 | + spin_lock_irqsave(&nvt->lock, flags); | |
| 185 | 186 | |
| 186 | 187 | nvt_clear_cir_wake_fifo(nvt); |
| 187 | 188 | nvt_cir_wake_reg_write(nvt, count, CIR_WAKE_FIFO_CMP_DEEP); |
| @@ -203,7 +204,7 @@ static void nvt_write_wakeup_codes(struct rc_dev *dev, · 15 unmodified lines | ||
| 203 | 204 | |
| 204 | 205 | nvt_cir_wake_reg_write(nvt, config, CIR_WAKE_IRCON); |
| 205 | 206 | |
| 206 | − spin_unlock(&nvt->lock); | |
| 207 | + spin_unlock_irqrestore(&nvt->lock, flags); | |
| 207 | 208 | } |
| 208 | 209 | |
| 209 | 210 | static ssize_t wakeup_data_show(struct device *dev, |
| @@ -1663,6 +1663,7 @@ static int rc_setup_rx_device(struct rc_dev *dev) · 1662 unmodified lines | ||
| 1663 | 1663 | { |
| 1664 | 1664 | int rc; |
| 1665 | 1665 | struct rc_map *rc_map; |
| 1666 | + u64 rc_type; | |
| 1666 | 1667 | |
| 1667 | 1668 | if (!dev->map_name) |
| 1668 | 1669 | return -EINVAL; |
| @@ -1677,15 +1678,18 @@ static int rc_setup_rx_device(struct rc_dev *dev) · 8 unmodified lines | ||
| 1677 | 1678 | if (rc) |
| 1678 | 1679 | return rc; |
| 1679 | 1680 | |
| 1680 | − if (dev->change_protocol) { | |
| 1681 | − u64 rc_type = (1ll << rc_map->rc_type); | |
| 1681 | + rc_type = BIT_ULL(rc_map->rc_type); | |
| 1682 | 1682 | |
| 1683 | + if (dev->change_protocol) { | |
| 1683 | 1684 | rc = dev->change_protocol(dev, &rc_type); |
| 1684 | 1685 | if (rc < 0) |
| 1685 | 1686 | goto out_table; |
| 1686 | 1687 | dev->enabled_protocols = rc_type; |
| 1687 | 1688 | } |
| 1688 | 1689 | |
| 1690 | + if (dev->driver_type == RC_DRIVER_IR_RAW) | |
| 1691 | + ir_raw_load_modules(&rc_type); | |
| 1692 | + | |
| 1689 | 1693 | set_bit(EV_KEY, dev->input_dev->evbit); |
| 1690 | 1694 | set_bit(EV_REP, dev->input_dev->evbit); |
| 1691 | 1695 | set_bit(EV_MSC, dev->input_dev->evbit); |
| @@ -1777,12 +1781,6 @@ int rc_register_device(struct rc_dev *dev) · 85 unmodified lines | ||
| 1777 | 1781 | dev->input_name ?: "Unspecified device", path ?: "N/A"); |
| 1778 | 1782 | kfree(path); |
| 1779 | 1783 | |
| 1780 | − if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { | |
| 1781 | − rc = rc_setup_rx_device(dev); | |
| 1782 | − if (rc) | |
| 1783 | − goto out_dev; | |
| 1784 | − } | |
| 1785 | − | |
| 1786 | 1784 | if (dev->driver_type == RC_DRIVER_IR_RAW || |
| 1787 | 1785 | dev->driver_type == RC_DRIVER_IR_RAW_TX) { |
| 1788 | 1786 | if (!raw_init) { |
| @@ -1791,7 +1789,13 @@ int rc_register_device(struct rc_dev *dev) · 2 unmodified lines | ||
| 1791 | 1789 | } |
| 1792 | 1790 | rc = ir_raw_event_register(dev); |
| 1793 | 1791 | if (rc < 0) |
| 1794 | − goto out_rx; | |
| 1792 | + goto out_dev; | |
| 1793 | + } | |
| 1794 | + | |
| 1795 | + if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { | |
| 1796 | + rc = rc_setup_rx_device(dev); | |
| 1797 | + if (rc) | |
| 1798 | + goto out_raw; | |
| 1795 | 1799 | } |
| 1796 | 1800 | |
| 1797 | 1801 | /* Allow the RC sysfs nodes to be accessible */ |
| @@ -1803,8 +1807,8 @@ int rc_register_device(struct rc_dev *dev) · 5 unmodified lines | ||
| 1803 | 1807 | |
| 1804 | 1808 | return 0; |
| 1805 | 1809 | |
| 1806 | −out_rx: | |
| 1807 | − rc_free_rx_device(dev); | |
| 1810 | +out_raw: | |
| 1811 | + ir_raw_event_unregister(dev); | |
| 1808 | 1812 | out_dev: |
| 1809 | 1813 | device_del(&dev->dev); |
| 1810 | 1814 | out_unlock: |
| @@ -487,10 +487,69 @@ static void serial_ir_timeout(unsigned long arg) · 486 unmodified lines | ||
| 487 | 487 | ir_raw_event_handle(serial_ir.rcdev); |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | +/* Needed by serial_ir_probe() */ | |
| 491 | +static int serial_ir_tx(struct rc_dev *dev, unsigned int *txbuf, | |
| 492 | + unsigned int count); | |
| 493 | +static int serial_ir_tx_duty_cycle(struct rc_dev *dev, u32 cycle); | |
| 494 | +static int serial_ir_tx_carrier(struct rc_dev *dev, u32 carrier); | |
| 495 | +static int serial_ir_open(struct rc_dev *rcdev); | |
| 496 | +static void serial_ir_close(struct rc_dev *rcdev); | |
| 497 | + | |
| 490 | 498 | static int serial_ir_probe(struct platform_device *dev) |
| 491 | 499 | { |
| 500 | + struct rc_dev *rcdev; | |
| 492 | 501 | int i, nlow, nhigh, result; |
| 493 | 502 | |
| 503 | + rcdev = devm_rc_allocate_device(&dev->dev, RC_DRIVER_IR_RAW); | |
| 504 | + if (!rcdev) | |
| 505 | + return -ENOMEM; | |
| 506 | + | |
| 507 | + if (hardware[type].send_pulse && hardware[type].send_space) | |
| 508 | + rcdev->tx_ir = serial_ir_tx; | |
| 509 | + if (hardware[type].set_send_carrier) | |
| 510 | + rcdev->s_tx_carrier = serial_ir_tx_carrier; | |
| 511 | + if (hardware[type].set_duty_cycle) | |
| 512 | + rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; | |
| 513 | + | |
| 514 | + switch (type) { | |
| 515 | + case IR_HOMEBREW: | |
| 516 | + rcdev->input_name = "Serial IR type home-brew"; | |
| 517 | + break; | |
| 518 | + case IR_IRDEO: | |
| 519 | + rcdev->input_name = "Serial IR type IRdeo"; | |
| 520 | + break; | |
| 521 | + case IR_IRDEO_REMOTE: | |
| 522 | + rcdev->input_name = "Serial IR type IRdeo remote"; | |
| 523 | + break; | |
| 524 | + case IR_ANIMAX: | |
| 525 | + rcdev->input_name = "Serial IR type AnimaX"; | |
| 526 | + break; | |
| 527 | + case IR_IGOR: | |
| 528 | + rcdev->input_name = "Serial IR type IgorPlug"; | |
| 529 | + break; | |
| 530 | + } | |
| 531 | + | |
| 532 | + rcdev->input_phys = KBUILD_MODNAME "/input0"; | |
| 533 | + rcdev->input_id.bustype = BUS_HOST; | |
| 534 | + rcdev->input_id.vendor = 0x0001; | |
| 535 | + rcdev->input_id.product = 0x0001; | |
| 536 | + rcdev->input_id.version = 0x0100; | |
| 537 | + rcdev->open = serial_ir_open; | |
| 538 | + rcdev->close = serial_ir_close; | |
| 539 | + rcdev->dev.parent = &serial_ir.pdev->dev; | |
| 540 | + rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; | |
| 541 | + rcdev->driver_name = KBUILD_MODNAME; | |
| 542 | + rcdev->map_name = RC_MAP_RC6_MCE; | |
| 543 | + rcdev->min_timeout = 1; | |
| 544 | + rcdev->timeout = IR_DEFAULT_TIMEOUT; | |
| 545 | + rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; | |
| 546 | + rcdev->rx_resolution = 250000; | |
| 547 | + | |
| 548 | + serial_ir.rcdev = rcdev; | |
| 549 | + | |
| 550 | + setup_timer(&serial_ir.timeout_timer, serial_ir_timeout, | |
| 551 | + (unsigned long)&serial_ir); | |
| 552 | + | |
| 494 | 553 | result = devm_request_irq(&dev->dev, irq, serial_ir_irq_handler, |
| 495 | 554 | share_irq ? IRQF_SHARED : 0, |
| 496 | 555 | KBUILD_MODNAME, &hardware); |
| @@ -516,9 +575,6 @@ static int serial_ir_probe(struct platform_device *dev) · 19 unmodified lines | ||
| 516 | 575 | return -EBUSY; |
| 517 | 576 | } |
| 518 | 577 | |
| 519 | − setup_timer(&serial_ir.timeout_timer, serial_ir_timeout, | |
| 520 | − (unsigned long)&serial_ir); | |
| 521 | − | |
| 522 | 578 | result = hardware_init_port(); |
| 523 | 579 | if (result < 0) |
| 524 | 580 | return result; |
| @@ -552,7 +608,8 @@ static int serial_ir_probe(struct platform_device *dev) · 27 unmodified lines | ||
| 552 | 608 | sense ? "low" : "high"); |
| 553 | 609 | |
| 554 | 610 | dev_dbg(&dev->dev, "Interrupt %d, port %04x obtained\n", irq, io); |
| 555 | − return 0; | |
| 611 | + | |
| 612 | + return devm_rc_register_device(&dev->dev, rcdev); | |
| 556 | 613 | } |
| 557 | 614 | |
| 558 | 615 | static int serial_ir_open(struct rc_dev *rcdev) |
| @@ -723,7 +780,6 @@ static void serial_ir_exit(void) · 164 unmodified lines | ||
| 723 | 780 | |
| 724 | 781 | static int __init serial_ir_init_module(void) |
| 725 | 782 | { |
| 726 | − struct rc_dev *rcdev; | |
| 727 | 783 | int result; |
| 728 | 784 | |
| 729 | 785 | switch (type) { |
| @@ -754,63 +810,9 @@ static int __init serial_ir_init_module(void) · 24 unmodified lines | ||
| 754 | 810 | sense = !!sense; |
| 755 | 811 | |
| 756 | 812 | result = serial_ir_init(); |
| 757 | − if (result) | |
| 758 | − return result; | |
| 759 | − | |
| 760 | − rcdev = devm_rc_allocate_device(&serial_ir.pdev->dev, RC_DRIVER_IR_RAW); | |
| 761 | − if (!rcdev) { | |
| 762 | − result = -ENOMEM; | |
| 763 | − goto serial_cleanup; | |
| 764 | − } | |
| 765 | − | |
| 766 | − if (hardware[type].send_pulse && hardware[type].send_space) | |
| 767 | − rcdev->tx_ir = serial_ir_tx; | |
| 768 | − if (hardware[type].set_send_carrier) | |
| 769 | − rcdev->s_tx_carrier = serial_ir_tx_carrier; | |
| 770 | − if (hardware[type].set_duty_cycle) | |
| 771 | − rcdev->s_tx_duty_cycle = serial_ir_tx_duty_cycle; | |
| 772 | − | |
| 773 | − switch (type) { | |
| 774 | − case IR_HOMEBREW: | |
| 775 | − rcdev->input_name = "Serial IR type home-brew"; | |
| 776 | − break; | |
| 777 | − case IR_IRDEO: | |
| 778 | − rcdev->input_name = "Serial IR type IRdeo"; | |
| 779 | − break; | |
| 780 | − case IR_IRDEO_REMOTE: | |
| 781 | − rcdev->input_name = "Serial IR type IRdeo remote"; | |
| 782 | − break; | |
| 783 | − case IR_ANIMAX: | |
| 784 | − rcdev->input_name = "Serial IR type AnimaX"; | |
| 785 | − break; | |
| 786 | − case IR_IGOR: | |
| 787 | − rcdev->input_name = "Serial IR type IgorPlug"; | |
| 788 | − break; | |
| 789 | − } | |
| 790 | − | |
| 791 | − rcdev->input_phys = KBUILD_MODNAME "/input0"; | |
| 792 | − rcdev->input_id.bustype = BUS_HOST; | |
| 793 | − rcdev->input_id.vendor = 0x0001; | |
| 794 | − rcdev->input_id.product = 0x0001; | |
| 795 | − rcdev->input_id.version = 0x0100; | |
| 796 | − rcdev->open = serial_ir_open; | |
| 797 | − rcdev->close = serial_ir_close; | |
| 798 | − rcdev->dev.parent = &serial_ir.pdev->dev; | |
| 799 | − rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; | |
| 800 | − rcdev->driver_name = KBUILD_MODNAME; | |
| 801 | − rcdev->map_name = RC_MAP_RC6_MCE; | |
| 802 | − rcdev->min_timeout = 1; | |
| 803 | − rcdev->timeout = IR_DEFAULT_TIMEOUT; | |
| 804 | − rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; | |
| 805 | − rcdev->rx_resolution = 250000; | |
| 806 | − | |
| 807 | − serial_ir.rcdev = rcdev; | |
| 808 | − | |
| 809 | − result = rc_register_device(rcdev); | |
| 810 | − | |
| 811 | 813 | if (!result) |
| 812 | 814 | return 0; |
| 813 | −serial_cleanup: | |
| 815 | + | |
| 814 | 816 | serial_ir_exit(); |
| 815 | 817 | return result; |
| 816 | 818 | } |
| @@ -818,7 +820,6 @@ serial_cleanup: · 1 unmodified line | ||
| 818 | 820 | static void __exit serial_ir_exit_module(void) |
| 819 | 821 | { |
| 820 | 822 | del_timer_sync(&serial_ir.timeout_timer); |
| 821 | − rc_unregister_device(serial_ir.rcdev); | |
| 822 | 823 | serial_ir_exit(); |
| 823 | 824 | } |
| 824 | 825 | |
| @@ -68,6 +68,7 @@ · 67 unmodified lines | ||
| 68 | 68 | struct dw2102_state { |
| 69 | 69 | u8 initialized; |
| 70 | 70 | u8 last_lock; |
| 71 | + u8 data[MAX_XFER_SIZE + 4]; | |
| 71 | 72 | struct i2c_client *i2c_client_demod; |
| 72 | 73 | struct i2c_client *i2c_client_tuner; |
| 73 | 74 | |
| @@ -661,62 +662,72 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], · 587 unmodified lines | ||
| 661 | 662 | int num) |
| 662 | 663 | { |
| 663 | 664 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
| 664 | − u8 obuf[0x40], ibuf[0x40]; | |
| 665 | + struct dw2102_state *state; | |
| 665 | 666 | |
| 666 | 667 | if (!d) |
| 667 | 668 | return -ENODEV; |
| 669 | + | |
| 670 | + state = d->priv; | |
| 671 | + | |
| 668 | 672 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
| 669 | 673 | return -EAGAIN; |
| 674 | + if (mutex_lock_interruptible(&d->data_mutex) < 0) { | |
| 675 | + mutex_unlock(&d->i2c_mutex); | |
| 676 | + return -EAGAIN; | |
| 677 | + } | |
| 670 | 678 | |
| 671 | 679 | switch (num) { |
| 672 | 680 | case 1: |
| 673 | 681 | switch (msg[0].addr) { |
| 674 | 682 | case SU3000_STREAM_CTRL: |
| 675 | − obuf[0] = msg[0].buf[0] + 0x36; | |
| 676 | − obuf[1] = 3; | |
| 677 | − obuf[2] = 0; | |
| 678 | − if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0) | |
| 683 | + state->data[0] = msg[0].buf[0] + 0x36; | |
| 684 | + state->data[1] = 3; | |
| 685 | + state->data[2] = 0; | |
| 686 | + if (dvb_usb_generic_rw(d, state->data, 3, | |
| 687 | + state->data, 0, 0) < 0) | |
| 679 | 688 | err("i2c transfer failed."); |
| 680 | 689 | break; |
| 681 | 690 | case DW2102_RC_QUERY: |
| 682 | − obuf[0] = 0x10; | |
| 683 | − if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0) | |
| 691 | + state->data[0] = 0x10; | |
| 692 | + if (dvb_usb_generic_rw(d, state->data, 1, | |
| 693 | + state->data, 2, 0) < 0) | |
| 684 | 694 | err("i2c transfer failed."); |
| 685 | − msg[0].buf[1] = ibuf[0]; | |
| 686 | − msg[0].buf[0] = ibuf[1]; | |
| 695 | + msg[0].buf[1] = state->data[0]; | |
| 696 | + msg[0].buf[0] = state->data[1]; | |
| 687 | 697 | break; |
| 688 | 698 | default: |
| 689 | 699 | /* always i2c write*/ |
| 690 | − obuf[0] = 0x08; | |
| 691 | − obuf[1] = msg[0].addr; | |
| 692 | − obuf[2] = msg[0].len; | |
| 700 | + state->data[0] = 0x08; | |
| 701 | + state->data[1] = msg[0].addr; | |
| 702 | + state->data[2] = msg[0].len; | |
| 693 | 703 | |
| 694 | − memcpy(&obuf[3], msg[0].buf, msg[0].len); | |
| 704 | + memcpy(&state->data[3], msg[0].buf, msg[0].len); | |
| 695 | 705 | |
| 696 | − if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3, | |
| 697 | − ibuf, 1, 0) < 0) | |
| 706 | + if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3, | |
| 707 | + state->data, 1, 0) < 0) | |
| 698 | 708 | err("i2c transfer failed."); |
| 699 | 709 | |
| 700 | 710 | } |
| 701 | 711 | break; |
| 702 | 712 | case 2: |
| 703 | 713 | /* always i2c read */ |
| 704 | − obuf[0] = 0x09; | |
| 705 | − obuf[1] = msg[0].len; | |
| 706 | − obuf[2] = msg[1].len; | |
| 707 | − obuf[3] = msg[0].addr; | |
| 708 | − memcpy(&obuf[4], msg[0].buf, msg[0].len); | |
| 709 | − | |
| 710 | − if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4, | |
| 711 | − ibuf, msg[1].len + 1, 0) < 0) | |
| 714 | + state->data[0] = 0x09; | |
| 715 | + state->data[1] = msg[0].len; | |
| 716 | + state->data[2] = msg[1].len; | |
| 717 | + state->data[3] = msg[0].addr; | |
| 718 | + memcpy(&state->data[4], msg[0].buf, msg[0].len); | |
| 719 | + | |
| 720 | + if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4, | |
| 721 | + state->data, msg[1].len + 1, 0) < 0) | |
| 712 | 722 | err("i2c transfer failed."); |
| 713 | 723 | |
| 714 | − memcpy(msg[1].buf, &ibuf[1], msg[1].len); | |
| 724 | + memcpy(msg[1].buf, &state->data[1], msg[1].len); | |
| 715 | 725 | break; |
| 716 | 726 | default: |
| 717 | 727 | warn("more than 2 i2c messages at a time is not handled yet."); |
| 718 | 728 | break; |
| 719 | 729 | } |
| 730 | + mutex_unlock(&d->data_mutex); | |
| 720 | 731 | mutex_unlock(&d->i2c_mutex); |
| 721 | 732 | return num; |
| 722 | 733 | } |
| @@ -844,17 +855,23 @@ static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) · 121 unmodified lines | ||
| 844 | 855 | static int su3000_power_ctrl(struct dvb_usb_device *d, int i) |
| 845 | 856 | { |
| 846 | 857 | struct dw2102_state *state = (struct dw2102_state *)d->priv; |
| 847 | − u8 obuf[] = {0xde, 0}; | |
| 858 | + int ret = 0; | |
| 848 | 859 | |
| 849 | 860 | info("%s: %d, initialized %d", __func__, i, state->initialized); |
| 850 | 861 | |
| 851 | 862 | if (i && !state->initialized) { |
| 863 | + mutex_lock(&d->data_mutex); | |
| 864 | + | |
| 865 | + state->data[0] = 0xde; | |
| 866 | + state->data[1] = 0; | |
| 867 | + | |
| 852 | 868 | state->initialized = 1; |
| 853 | 869 | /* reset board */ |
| 854 | − return dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0); | |
| 870 | + ret = dvb_usb_generic_rw(d, state->data, 2, NULL, 0, 0); | |
| 871 | + mutex_unlock(&d->data_mutex); | |
| 855 | 872 | } |
| 856 | 873 | |
| 857 | − return 0; | |
| 874 | + return ret; | |
| 858 | 875 | } |
| 859 | 876 | |
| 860 | 877 | static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) |
| @@ -1309,49 +1326,57 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) · 448 unmodified lines | ||
| 1309 | 1326 | return 0; |
| 1310 | 1327 | } |
| 1311 | 1328 | |
| 1312 | −static int su3000_frontend_attach(struct dvb_usb_adapter *d) | |
| 1329 | +static int su3000_frontend_attach(struct dvb_usb_adapter *adap) | |
| 1313 | 1330 | { |
| 1314 | − u8 obuf[3] = { 0xe, 0x80, 0 }; | |
| 1315 | − u8 ibuf[] = { 0 }; | |
| 1331 | + struct dvb_usb_device *d = adap->dev; | |
| 1332 | + struct dw2102_state *state = d->priv; | |
| 1333 | + | |
| 1334 | + mutex_lock(&d->data_mutex); | |
| 1335 | + | |
| 1336 | + state->data[0] = 0xe; | |
| 1337 | + state->data[1] = 0x80; | |
| 1338 | + state->data[2] = 0; | |
| 1316 | 1339 | |
| 1317 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1340 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1318 | 1341 | err("command 0x0e transfer failed."); |
| 1319 | 1342 | |
| 1320 | − obuf[0] = 0xe; | |
| 1321 | − obuf[1] = 0x02; | |
| 1322 | − obuf[2] = 1; | |
| 1343 | + state->data[0] = 0xe; | |
| 1344 | + state->data[1] = 0x02; | |
| 1345 | + state->data[2] = 1; | |
| 1323 | 1346 | |
| 1324 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1347 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1325 | 1348 | err("command 0x0e transfer failed."); |
| 1326 | 1349 | msleep(300); |
| 1327 | 1350 | |
| 1328 | − obuf[0] = 0xe; | |
| 1329 | − obuf[1] = 0x83; | |
| 1330 | − obuf[2] = 0; | |
| 1351 | + state->data[0] = 0xe; | |
| 1352 | + state->data[1] = 0x83; | |
| 1353 | + state->data[2] = 0; | |
| 1331 | 1354 | |
| 1332 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1355 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1333 | 1356 | err("command 0x0e transfer failed."); |
| 1334 | 1357 | |
| 1335 | − obuf[0] = 0xe; | |
| 1336 | − obuf[1] = 0x83; | |
| 1337 | − obuf[2] = 1; | |
| 1358 | + state->data[0] = 0xe; | |
| 1359 | + state->data[1] = 0x83; | |
| 1360 | + state->data[2] = 1; | |
| 1338 | 1361 | |
| 1339 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1362 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1340 | 1363 | err("command 0x0e transfer failed."); |
| 1341 | 1364 | |
| 1342 | − obuf[0] = 0x51; | |
| 1365 | + state->data[0] = 0x51; | |
| 1343 | 1366 | |
| 1344 | − if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | |
| 1367 | + if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) | |
| 1345 | 1368 | err("command 0x51 transfer failed."); |
| 1346 | 1369 | |
| 1347 | − d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, | |
| 1348 | − &d->dev->i2c_adap); | |
| 1349 | − if (d->fe_adap[0].fe == NULL) | |
| 1370 | + mutex_unlock(&d->data_mutex); | |
| 1371 | + | |
| 1372 | + adap->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, | |
| 1373 | + &d->i2c_adap); | |
| 1374 | + if (adap->fe_adap[0].fe == NULL) | |
| 1350 | 1375 | return -EIO; |
| 1351 | 1376 | |
| 1352 | − if (dvb_attach(ts2020_attach, d->fe_adap[0].fe, | |
| 1377 | + if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, | |
| 1353 | 1378 | &dw2104_ts2020_config, |
| 1354 | − &d->dev->i2c_adap)) { | |
| 1379 | + &d->i2c_adap)) { | |
| 1355 | 1380 | info("Attached DS3000/TS2020!"); |
| 1356 | 1381 | return 0; |
| 1357 | 1382 | } |
| @@ -1360,47 +1385,55 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d) · 2 unmodified lines | ||
| 1360 | 1385 | return -EIO; |
| 1361 | 1386 | } |
| 1362 | 1387 | |
| 1363 | −static int t220_frontend_attach(struct dvb_usb_adapter *d) | |
| 1388 | +static int t220_frontend_attach(struct dvb_usb_adapter *adap) | |
| 1364 | 1389 | { |
| 1365 | − u8 obuf[3] = { 0xe, 0x87, 0 }; | |
| 1366 | − u8 ibuf[] = { 0 }; | |
| 1390 | + struct dvb_usb_device *d = adap->dev; | |
| 1391 | + struct dw2102_state *state = d->priv; | |
| 1392 | + | |
| 1393 | + mutex_lock(&d->data_mutex); | |
| 1367 | 1394 | |
| 1368 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1395 | + state->data[0] = 0xe; | |
| 1396 | + state->data[1] = 0x87; | |
| 1397 | + state->data[2] = 0x0; | |
| 1398 | + | |
| 1399 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1369 | 1400 | err("command 0x0e transfer failed."); |
| 1370 | 1401 | |
| 1371 | − obuf[0] = 0xe; | |
| 1372 | − obuf[1] = 0x86; | |
| 1373 | − obuf[2] = 1; | |
| 1402 | + state->data[0] = 0xe; | |
| 1403 | + state->data[1] = 0x86; | |
| 1404 | + state->data[2] = 1; | |
| 1374 | 1405 | |
| 1375 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1406 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1376 | 1407 | err("command 0x0e transfer failed."); |
| 1377 | 1408 | |
| 1378 | − obuf[0] = 0xe; | |
| 1379 | − obuf[1] = 0x80; | |
| 1380 | − obuf[2] = 0; | |
| 1409 | + state->data[0] = 0xe; | |
| 1410 | + state->data[1] = 0x80; | |
| 1411 | + state->data[2] = 0; | |
| 1381 | 1412 | |
| 1382 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1413 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1383 | 1414 | err("command 0x0e transfer failed."); |
| 1384 | 1415 | |
| 1385 | 1416 | msleep(50); |
| 1386 | 1417 | |
| 1387 | − obuf[0] = 0xe; | |
| 1388 | − obuf[1] = 0x80; | |
| 1389 | − obuf[2] = 1; | |
| 1418 | + state->data[0] = 0xe; | |
| 1419 | + state->data[1] = 0x80; | |
| 1420 | + state->data[2] = 1; | |
| 1390 | 1421 | |
| 1391 | − if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | |
| 1422 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1392 | 1423 | err("command 0x0e transfer failed."); |
| 1393 | 1424 | |
| 1394 | − obuf[0] = 0x51; | |
| 1425 | + state->data[0] = 0x51; | |
| 1395 | 1426 | |
| 1396 | − if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | |
| 1427 | + if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) | |
| 1397 | 1428 | err("command 0x51 transfer failed."); |
| 1398 | 1429 | |
| 1399 | − d->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, | |
| 1400 | − &d->dev->i2c_adap, NULL); | |
| 1401 | − if (d->fe_adap[0].fe != NULL) { | |
| 1402 | − if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60, | |
| 1403 | − &d->dev->i2c_adap, &tda18271_config)) { | |
| 1430 | + mutex_unlock(&d->data_mutex); | |
| 1431 | + | |
| 1432 | + adap->fe_adap[0].fe = dvb_attach(cxd2820r_attach, &cxd2820r_config, | |
| 1433 | + &d->i2c_adap, NULL); | |
| 1434 | + if (adap->fe_adap[0].fe != NULL) { | |
| 1435 | + if (dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0x60, | |
| 1436 | + &d->i2c_adap, &tda18271_config)) { | |
| 1404 | 1437 | info("Attached TDA18271HD/CXD2820R!"); |
| 1405 | 1438 | return 0; |
| 1406 | 1439 | } |
| @@ -1410,23 +1443,30 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d) · 3 unmodified lines | ||
| 1410 | 1443 | return -EIO; |
| 1411 | 1444 | } |
| 1412 | 1445 | |
| 1413 | −static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d) | |
| 1446 | +static int m88rs2000_frontend_attach(struct dvb_usb_adapter *adap) | |
| 1414 | 1447 | { |
| 1415 | − u8 obuf[] = { 0x51 }; | |
| 1416 | − u8 ibuf[] = { 0 }; | |
| 1448 | + struct dvb_usb_device *d = adap->dev; | |
| 1449 | + struct dw2102_state *state = d->priv; | |
| 1450 | + | |
| 1451 | + mutex_lock(&d->data_mutex); | |
| 1417 | 1452 | |
| 1418 | − if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | |
| 1453 | + state->data[0] = 0x51; | |
| 1454 | + | |
| 1455 | + if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) | |
| 1419 | 1456 | err("command 0x51 transfer failed."); |
| 1420 | 1457 | |
| 1421 | − d->fe_adap[0].fe = dvb_attach(m88rs2000_attach, &s421_m88rs2000_config, | |
| 1422 | − &d->dev->i2c_adap); | |
| 1458 | + mutex_unlock(&d->data_mutex); | |
| 1423 | 1459 | |
| 1424 | − if (d->fe_adap[0].fe == NULL) | |
| 1460 | + adap->fe_adap[0].fe = dvb_attach(m88rs2000_attach, | |
| 1461 | + &s421_m88rs2000_config, | |
| 1462 | + &d->i2c_adap); | |
| 1463 | + | |
| 1464 | + if (adap->fe_adap[0].fe == NULL) | |
| 1425 | 1465 | return -EIO; |
| 1426 | 1466 | |
| 1427 | − if (dvb_attach(ts2020_attach, d->fe_adap[0].fe, | |
| 1467 | + if (dvb_attach(ts2020_attach, adap->fe_adap[0].fe, | |
| 1428 | 1468 | &dw2104_ts2020_config, |
| 1429 | − &d->dev->i2c_adap)) { | |
| 1469 | + &d->i2c_adap)) { | |
| 1430 | 1470 | info("Attached RS2000/TS2020!"); |
| 1431 | 1471 | return 0; |
| 1432 | 1472 | } |
| @@ -1439,44 +1479,50 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) · 6 unmodified lines | ||
| 1439 | 1479 | { |
| 1440 | 1480 | struct dvb_usb_device *d = adap->dev; |
| 1441 | 1481 | struct dw2102_state *state = d->priv; |
| 1442 | − u8 obuf[3] = { 0xe, 0x80, 0 }; | |
| 1443 | − u8 ibuf[] = { 0 }; | |
| 1444 | 1482 | struct i2c_adapter *i2c_adapter; |
| 1445 | 1483 | struct i2c_client *client; |
| 1446 | 1484 | struct i2c_board_info board_info; |
| 1447 | 1485 | struct m88ds3103_platform_data m88ds3103_pdata = {}; |
| 1448 | 1486 | struct ts2020_config ts2020_config = {}; |
| 1449 | 1487 | |
| 1450 | − if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | |
| 1488 | + mutex_lock(&d->data_mutex); | |
| 1489 | + | |
| 1490 | + state->data[0] = 0xe; | |
| 1491 | + state->data[1] = 0x80; | |
| 1492 | + state->data[2] = 0x0; | |
| 1493 | + | |
| 1494 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1451 | 1495 | err("command 0x0e transfer failed."); |
| 1452 | 1496 | |
| 1453 | − obuf[0] = 0xe; | |
| 1454 | − obuf[1] = 0x02; | |
| 1455 | − obuf[2] = 1; | |
| 1497 | + state->data[0] = 0xe; | |
| 1498 | + state->data[1] = 0x02; | |
| 1499 | + state->data[2] = 1; | |
| 1456 | 1500 | |
| 1457 | − if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | |
| 1501 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1458 | 1502 | err("command 0x0e transfer failed."); |
| 1459 | 1503 | msleep(300); |
| 1460 | 1504 | |
| 1461 | − obuf[0] = 0xe; | |
| 1462 | − obuf[1] = 0x83; | |
| 1463 | − obuf[2] = 0; | |
| 1505 | + state->data[0] = 0xe; | |
| 1506 | + state->data[1] = 0x83; | |
| 1507 | + state->data[2] = 0; | |
| 1464 | 1508 | |
| 1465 | − if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | |
| 1509 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1466 | 1510 | err("command 0x0e transfer failed."); |
| 1467 | 1511 | |
| 1468 | − obuf[0] = 0xe; | |
| 1469 | − obuf[1] = 0x83; | |
| 1470 | − obuf[2] = 1; | |
| 1512 | + state->data[0] = 0xe; | |
| 1513 | + state->data[1] = 0x83; | |
| 1514 | + state->data[2] = 1; | |
| 1471 | 1515 | |
| 1472 | − if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 1, 0) < 0) | |
| 1516 | + if (dvb_usb_generic_rw(d, state->data, 3, state->data, 1, 0) < 0) | |
| 1473 | 1517 | err("command 0x0e transfer failed."); |
| 1474 | 1518 | |
| 1475 | − obuf[0] = 0x51; | |
| 1519 | + state->data[0] = 0x51; | |
| 1476 | 1520 | |
| 1477 | − if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 1, 0) < 0) | |
| 1521 | + if (dvb_usb_generic_rw(d, state->data, 1, state->data, 1, 0) < 0) | |
| 1478 | 1522 | err("command 0x51 transfer failed."); |
| 1479 | 1523 | |
| 1524 | + mutex_unlock(&d->data_mutex); | |
| 1525 | + | |
| 1480 | 1526 | /* attach demod */ |
| 1481 | 1527 | m88ds3103_pdata.clk = 27000000; |
| 1482 | 1528 | m88ds3103_pdata.i2c_wr_max = 33; |
| @@ -20,8 +20,17 @@ struct device; · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | int vsp1_du_init(struct device *dev); |
| 22 | 22 | |
| 23 | −int vsp1_du_setup_lif(struct device *dev, unsigned int width, | |
| 24 | − unsigned int height); | |
| 23 | +/** | |
| 24 | + * struct vsp1_du_lif_config - VSP LIF configuration | |
| 25 | + * @width: output frame width | |
| 26 | + * @height: output frame height | |
| 27 | + */ | |
| 28 | +struct vsp1_du_lif_config { | |
| 29 | + unsigned int width; | |
| 30 | + unsigned int height; | |
| 31 | +}; | |
| 32 | + | |
| 33 | +int vsp1_du_setup_lif(struct device *dev, const struct vsp1_du_lif_config *cfg); | |
| 25 | 34 | |
| 26 | 35 | struct vsp1_du_atomic_config { |
| 27 | 36 | u32 pixelformat; |