summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/Kconfig3
-rw-r--r--drivers/media/cec/cec-adap.c112
-rw-r--r--drivers/media/cec/cec-api.c8
-rw-r--r--drivers/media/cec/cec-core.c3
-rw-r--r--drivers/media/cec/cec-priv.h5
-rw-r--r--drivers/media/common/videobuf2/videobuf2-core.c5
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-sg.c2
-rw-r--r--drivers/media/dvb-core/Kconfig3
-rw-r--r--drivers/media/dvb-frontends/Kconfig3
-rw-r--r--drivers/media/dvb-frontends/si2168.c7
-rw-r--r--drivers/media/i2c/Kconfig4
-rw-r--r--drivers/media/i2c/ov7740.c24
-rw-r--r--drivers/media/i2c/smiapp/smiapp-quirk.c2
-rw-r--r--drivers/media/media-device.c9
-rw-r--r--drivers/media/pci/ddbridge/Kconfig1
-rw-r--r--drivers/media/pci/dt3155/Kconfig1
-rw-r--r--drivers/media/pci/ivtv/Kconfig2
-rw-r--r--drivers/media/platform/Kconfig12
-rw-r--r--drivers/media/platform/atmel/atmel-isc-regs.h6
-rw-r--r--drivers/media/platform/atmel/atmel-isc.c263
-rw-r--r--drivers/media/platform/cec-gpio/cec-gpio.c28
-rw-r--r--drivers/media/platform/coda/Makefile1
-rw-r--r--drivers/media/platform/coda/coda-bit.c56
-rw-r--r--drivers/media/platform/coda/coda-common.c81
-rw-r--r--drivers/media/platform/coda/coda-h264.c3
-rw-r--r--drivers/media/platform/coda/coda.h3
-rw-r--r--drivers/media/platform/coda/coda_regs.h2
-rw-r--r--drivers/media/platform/coda/trace.h2
-rw-r--r--drivers/media/platform/davinci/vpss.c7
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c6
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c11
-rw-r--r--drivers/media/platform/omap/Kconfig1
-rw-r--r--drivers/media/platform/qcom/venus/core.c4
-rw-r--r--drivers/media/platform/qcom/venus/firmware.c6
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c7
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.c2
-rw-r--r--drivers/media/platform/qcom/venus/venc_ctrls.c21
-rw-r--r--drivers/media/platform/vicodec/Kconfig1
-rw-r--r--drivers/media/platform/vimc/Kconfig1
-rw-r--r--drivers/media/platform/vivid/Kconfig1
-rw-r--r--drivers/media/radio/Kconfig1
-rw-r--r--drivers/media/rc/ir-spi.c1
-rw-r--r--drivers/media/rc/meson-ir.c8
-rw-r--r--drivers/media/rc/rc-main.c6
-rw-r--r--drivers/media/spi/Kconfig2
-rw-r--r--drivers/media/tuners/Kconfig2
-rw-r--r--drivers/media/usb/au0828/au0828-core.c12
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c15
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c11
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c7
-rw-r--r--drivers/media/usb/s2255/Kconfig1
-rw-r--r--drivers/media/v4l2-core/Kconfig2
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c1
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c8
55 files changed, 550 insertions, 248 deletions
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 092e7509af9b..ce6782bc53ef 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -114,7 +114,6 @@ config MEDIA_CONTROLLER_DVB
config MEDIA_CONTROLLER_REQUEST_API
bool "Enable Media controller Request API (EXPERIMENTAL)"
depends on MEDIA_CONTROLLER && STAGING_MEDIA
- default n
help
DO NOT ENABLE THIS OPTION UNLESS YOU KNOW WHAT YOU'RE DOING.
@@ -164,7 +163,6 @@ config DVB_MMAP
depends on DVB_CORE
depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
select VIDEOBUF2_VMALLOC
- default n
help
This option enables DVB experimental memory-mapped API, which
reduces the number of context switches to read DVB buffers, as
@@ -190,7 +188,6 @@ config DVB_NET
config TTPCI_EEPROM
tristate
depends on I2C
- default n
source "drivers/media/dvb-core/Kconfig"
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index f1261cc2b6fa..5827d8c3742a 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -720,6 +720,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
struct cec_fh *fh, bool block)
{
struct cec_data *data;
+ bool is_raw = msg_is_raw(msg);
msg->rx_ts = 0;
msg->tx_ts = 0;
@@ -735,15 +736,10 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
/* Make sure the timeout isn't 0. */
msg->timeout = 1000;
}
- if (msg->timeout)
- msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS;
- else
- msg->flags = 0;
+ msg->flags &= CEC_MSG_FL_REPLY_TO_FOLLOWERS | CEC_MSG_FL_RAW;
- if (msg->len > 1 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
- msg->msg[2] = adap->phys_addr >> 8;
- msg->msg[3] = adap->phys_addr & 0xff;
- }
+ if (!msg->timeout)
+ msg->flags &= ~CEC_MSG_FL_REPLY_TO_FOLLOWERS;
/* Sanity checks */
if (msg->len == 0 || msg->len > CEC_MAX_MSG_SIZE) {
@@ -765,44 +761,80 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
dprintk(1, "%s: can't reply to poll msg\n", __func__);
return -EINVAL;
}
- if (msg->len == 1) {
- if (cec_msg_destination(msg) == 0xf) {
- dprintk(1, "%s: invalid poll message\n", __func__);
+
+ if (is_raw) {
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+ } else {
+ /* A CDC-Only device can only send CDC messages */
+ if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
+ (msg->len == 1 || msg->msg[1] != CEC_MSG_CDC_MESSAGE)) {
+ dprintk(1, "%s: not a CDC message\n", __func__);
return -EINVAL;
}
- if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
- /*
- * If the destination is a logical address our adapter
- * has already claimed, then just NACK this.
- * It depends on the hardware what it will do with a
- * POLL to itself (some OK this), so it is just as
- * easy to handle it here so the behavior will be
- * consistent.
- */
- msg->tx_ts = ktime_get_ns();
- msg->tx_status = CEC_TX_STATUS_NACK |
- CEC_TX_STATUS_MAX_RETRIES;
- msg->tx_nack_cnt = 1;
- msg->sequence = ++adap->sequence;
- if (!msg->sequence)
+
+ if (msg->len >= 4 && msg->msg[1] == CEC_MSG_CDC_MESSAGE) {
+ msg->msg[2] = adap->phys_addr >> 8;
+ msg->msg[3] = adap->phys_addr & 0xff;
+ }
+
+ if (msg->len == 1) {
+ if (cec_msg_destination(msg) == 0xf) {
+ dprintk(1, "%s: invalid poll message\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (cec_has_log_addr(adap, cec_msg_destination(msg))) {
+ /*
+ * If the destination is a logical address our
+ * adapter has already claimed, then just NACK
+ * this. It depends on the hardware what it will
+ * do with a POLL to itself (some OK this), so
+ * it is just as easy to handle it here so the
+ * behavior will be consistent.
+ */
+ msg->tx_ts = ktime_get_ns();
+ msg->tx_status = CEC_TX_STATUS_NACK |
+ CEC_TX_STATUS_MAX_RETRIES;
+ msg->tx_nack_cnt = 1;
msg->sequence = ++adap->sequence;
- return 0;
+ if (!msg->sequence)
+ msg->sequence = ++adap->sequence;
+ return 0;
+ }
+ }
+ if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
+ cec_has_log_addr(adap, cec_msg_destination(msg))) {
+ dprintk(1, "%s: destination is the adapter itself\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (adap->is_configured &&
+ !cec_has_log_addr(adap, cec_msg_initiator(msg))) {
+ dprintk(1, "%s: initiator has unknown logical address %d\n",
+ __func__, cec_msg_initiator(msg));
+ return -EINVAL;
+ }
+ /*
+ * Special case: allow Ping and IMAGE/TEXT_VIEW_ON to be
+ * transmitted to a TV, even if the adapter is unconfigured.
+ * This makes it possible to detect or wake up displays that
+ * pull down the HPD when in standby.
+ */
+ if (!adap->is_configured && !adap->is_configuring &&
+ (msg->len > 2 ||
+ cec_msg_destination(msg) != CEC_LOG_ADDR_TV ||
+ (msg->len == 2 && msg->msg[1] != CEC_MSG_IMAGE_VIEW_ON &&
+ msg->msg[1] != CEC_MSG_TEXT_VIEW_ON))) {
+ dprintk(1, "%s: adapter is unconfigured\n", __func__);
+ return -ENONET;
}
}
- if (msg->len > 1 && !cec_msg_is_broadcast(msg) &&
- cec_has_log_addr(adap, cec_msg_destination(msg))) {
- dprintk(1, "%s: destination is the adapter itself\n", __func__);
- return -EINVAL;
- }
- if (msg->len > 1 && adap->is_configured &&
- !cec_has_log_addr(adap, cec_msg_initiator(msg))) {
- dprintk(1, "%s: initiator has unknown logical address %d\n",
- __func__, cec_msg_initiator(msg));
- return -EINVAL;
- }
+
if (!adap->is_configured && !adap->is_configuring) {
- if (adap->needs_hpd || msg->msg[0] != 0xf0) {
- dprintk(1, "%s: adapter is unconfigured\n", __func__);
+ if (adap->needs_hpd) {
+ dprintk(1, "%s: adapter is unconfigured and needs HPD\n",
+ __func__);
return -ENONET;
}
if (msg->reply) {
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 156a0d76ab2a..12d676484472 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -198,19 +198,11 @@ static long cec_transmit(struct cec_adapter *adap, struct cec_fh *fh,
if (copy_from_user(&msg, parg, sizeof(msg)))
return -EFAULT;
- /* A CDC-Only device can only send CDC messages */
- if ((adap->log_addrs.flags & CEC_LOG_ADDRS_FL_CDC_ONLY) &&
- (msg.len == 1 || msg.msg[1] != CEC_MSG_CDC_MESSAGE))
- return -EINVAL;
-
mutex_lock(&adap->lock);
if (adap->log_addrs.num_log_addrs == 0)
err = -EPERM;
else if (adap->is_configuring)
err = -ENONET;
- else if (!adap->is_configured &&
- (adap->needs_hpd || msg.msg[0] != 0xf0))
- err = -ENONET;
else if (cec_is_busy(adap, fh))
err = -EBUSY;
else
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index f5d1578e256a..db7adffcdc76 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -128,13 +128,14 @@ static int __must_check cec_devnode_register(struct cec_devnode *devnode,
devnode->cdev.owner = owner;
kobject_set_name(&devnode->cdev.kobj, "cec%d", devnode->minor);
+ devnode->registered = true;
ret = cdev_device_add(&devnode->cdev, &devnode->dev);
if (ret) {
+ devnode->registered = false;
pr_err("%s: cdev_device_add failed\n", __func__);
goto clr_bit;
}
- devnode->registered = true;
return 0;
clr_bit:
diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h
index 804e38f849c7..7bdf855aaecd 100644
--- a/drivers/media/cec/cec-priv.h
+++ b/drivers/media/cec/cec-priv.h
@@ -20,6 +20,11 @@
/* devnode to cec_adapter */
#define to_cec_adapter(node) container_of(node, struct cec_adapter, devnode)
+static inline bool msg_is_raw(const struct cec_msg *msg)
+{
+ return msg->flags & CEC_MSG_FL_RAW;
+}
+
/* cec-core.c */
extern int cec_debug;
int cec_get_device(struct cec_devnode *devnode);
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index 3cf25abf5807..4489744fbbd9 100644
--- a/drivers/media/common/videobuf2/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -205,8 +205,13 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
* NOTE: mmapped areas should be page aligned
*/
for (plane = 0; plane < vb->num_planes; ++plane) {
+ /* Memops alloc requires size to be page aligned. */
unsigned long size = PAGE_ALIGN(vb->planes[plane].length);
+ /* Did it wrap around? */
+ if (size < vb->planes[plane].length)
+ goto free;
+
mem_priv = call_ptr_memop(vb, alloc,
q->alloc_devs[plane] ? : q->dev,
q->dma_attrs, size, q->dma_dir, q->gfp_flags);
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 4a4c49d6085c..0f06f08346ba 100644
--- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -59,7 +59,7 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
gfp_t gfp_flags)
{
unsigned int last_page = 0;
- int size = buf->size;
+ unsigned long size = buf->size;
while (size > 0) {
struct page *pages;
diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig
index aac4bebb35f7..90e038d5ffd9 100644
--- a/drivers/media/dvb-core/Kconfig
+++ b/drivers/media/dvb-core/Kconfig
@@ -19,7 +19,6 @@ config DVB_MAX_ADAPTERS
config DVB_DYNAMIC_MINORS
bool "Dynamic DVB minor allocation"
depends on DVB_CORE
- default n
help
If you say Y here, the DVB subsystem will use dynamic minor
allocation for any device that uses the DVB major number.
@@ -32,7 +31,6 @@ config DVB_DYNAMIC_MINORS
config DVB_DEMUX_SECTION_LOSS_LOG
bool "Enable DVB demux section packet loss log"
depends on DVB_CORE
- default n
help
Enable extra log messages meant to detect packet loss
inside the Kernel.
@@ -45,7 +43,6 @@ config DVB_DEMUX_SECTION_LOSS_LOG
config DVB_ULE_DEBUG
bool "Enable DVB net ULE packet debug messages"
depends on DVB_CORE
- default n
help
Enable extra log messages meant to detect problems while
handling DVB network ULE packet loss inside the Kernel.
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 847da72d1256..dc43749177df 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -1,5 +1,5 @@
menu "Customise DVB Frontends"
- visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
+ visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -945,5 +945,4 @@ comment "Tools to develop new frontends"
config DVB_DUMMY_FE
tristate "Dummy frontend driver"
depends on DVB_CORE
- default n
endmenu
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 324493e05f9f..17301c6701d4 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -683,8 +683,11 @@ static const struct dvb_frontend_ops si2168_ops = {
.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
.info = {
.name = "Silicon Labs Si2168",
- .symbol_rate_min = 1000000,
- .symbol_rate_max = 7200000,
+ .frequency_min_hz = 48 * MHz,
+ .frequency_max_hz = 870 * MHz,
+ .frequency_stepsize_hz = 62500,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 7200000,
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cb8db944aa41..95d42730745c 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -6,7 +6,7 @@
if VIDEO_V4L2
config VIDEO_IR_I2C
- tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT
+ tristate "I2C module for IR" if !MEDIA_SUBDRV_AUTOSELECT || EXPERT
depends on I2C && RC_CORE
default y
help
@@ -23,7 +23,7 @@ config VIDEO_IR_I2C
#
menu "I2C Encoders, decoders, sensors and other helper chips"
- visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
+ visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
comment "Audio decoders, processors and mixers"
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 54e80a60aa57..70bb870b1d08 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -532,7 +532,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
struct regmap *regmap = ov7740->regmap;
int ret;
- u8 val = 0;
+ u8 val;
if (!pm_runtime_get_if_in_use(&client->dev))
return 0;
@@ -551,6 +551,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
ret = ov7740_set_contrast(regmap, ctrl->val);
break;
case V4L2_CID_VFLIP:
+ val = ctrl->val ? REG0C_IMG_FLIP : 0x00;
ret = regmap_update_bits(regmap, REG_REG0C,
REG0C_IMG_FLIP, val);
break;
@@ -561,16 +562,16 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_AUTOGAIN:
if (!ctrl->val)
- return ov7740_set_gain(regmap, ov7740->gain->val);
-
- ret = ov7740_set_autogain(regmap, ctrl->val);
+ ret = ov7740_set_gain(regmap, ov7740->gain->val);
+ else
+ ret = ov7740_set_autogain(regmap, ctrl->val);
break;
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->val == V4L2_EXPOSURE_MANUAL)
- return ov7740_set_exp(regmap, ov7740->exposure->val);
-
- ret = ov7740_set_autoexp(regmap, ctrl->val);
+ ret = ov7740_set_exp(regmap, ov7740->exposure->val);
+ else
+ ret = ov7740_set_autoexp(regmap, ctrl->val);
break;
default:
ret = -EINVAL;
@@ -785,7 +786,11 @@ static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
fsize++;
}
-
+ if (i >= ARRAY_SIZE(ov7740_framesizes)) {
+ fsize = &ov7740_framesizes[0];
+ fmt->width = fsize->width;
+ fmt->height = fsize->height;
+ }
if (ret_frmsize != NULL)
*ret_frmsize = fsize;
@@ -1007,8 +1012,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
V4L2_CID_GAIN, 0, 1023, 1, 500);
- if (ov7740->gain)
- ov7740->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
@@ -1026,7 +1029,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
V4L2_EXPOSURE_MANUAL, true);
- v4l2_ctrl_cluster(2, &ov7740->hflip);
if (ctrl_hdlr->error) {
ret = ctrl_hdlr->error;
diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.c b/drivers/media/i2c/smiapp/smiapp-quirk.c
index 95c0272bb014..59cb2a51758a 100644
--- a/drivers/media/i2c/smiapp/smiapp-quirk.c
+++ b/drivers/media/i2c/smiapp/smiapp-quirk.c
@@ -202,7 +202,7 @@ static int jt8ev1_post_streamoff(struct smiapp_sensor *sensor)
return rval;
/* Wait for 1 ms + one line => 2 ms is likely enough */
- usleep_range(2000, 2000);
+ usleep_range(2000, 2050);
/* Restore it */
rval = smiapp_write_8(sensor, 0x3205, 0x00);
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index b8ec88612df7..6893843edada 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -502,6 +502,7 @@ static long media_device_enum_links32(struct media_device *mdev,
{
struct media_links_enum links;
compat_uptr_t pads_ptr, links_ptr;
+ int ret;
memset(&links, 0, sizeof(links));
@@ -513,7 +514,13 @@ static long media_device_enum_links32(struct media_device *mdev,
links.pads = compat_ptr(pads_ptr);
links.links = compat_ptr(links_ptr);
- return media_device_enum_links(mdev, &links);
+ ret = media_device_enum_links(mdev, &links);
+ if (ret)
+ return ret;
+
+ memset(ulinks->reserved, 0, sizeof(ulinks->reserved));
+
+ return 0;
}
#define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32)
diff --git a/drivers/media/pci/ddbridge/Kconfig b/drivers/media/pci/ddbridge/Kconfig
index eaac91d14654..dab34fb85c09 100644
--- a/drivers/media/pci/ddbridge/Kconfig
+++ b/drivers/media/pci/ddbridge/Kconfig
@@ -36,7 +36,6 @@ config DVB_DDBRIDGE_MSIENABLE
bool "Enable Message Signaled Interrupts (MSI) per default (EXPERIMENTAL)"
depends on DVB_DDBRIDGE
depends on PCI_MSI
- default n
help
Use PCI MSI (Message Signaled Interrupts) per default. Enabling this
might lead to I2C errors originating from the bridge in conjunction
diff --git a/drivers/media/pci/dt3155/Kconfig b/drivers/media/pci/dt3155/Kconfig
index d678ced93f17..a3d24b8a719b 100644
--- a/drivers/media/pci/dt3155/Kconfig
+++ b/drivers/media/pci/dt3155/Kconfig
@@ -3,7 +3,6 @@ config VIDEO_DT3155
tristate "DT3155 frame grabber"
depends on PCI && VIDEO_DEV && VIDEO_V4L2
select VIDEOBUF2_DMA_CONTIG
- default n
help
Enables dt3155 device driver for the DataTranslation DT3155 frame grabber.
Say Y here if you have this hardware.
diff --git a/drivers/media/pci/ivtv/Kconfig b/drivers/media/pci/ivtv/Kconfig
index 079569955fb4..36c089103cf9 100644
--- a/drivers/media/pci/ivtv/Kconfig
+++ b/drivers/media/pci/ivtv/Kconfig
@@ -32,7 +32,6 @@ config VIDEO_IVTV
config VIDEO_IVTV_DEPRECATED_IOCTLS
bool "enable the DVB ioctls abuse on ivtv driver"
depends on VIDEO_IVTV
- default n
help
Enable the usage of the a DVB set of ioctls that were abused by
IVTV driver for a while.
@@ -77,7 +76,6 @@ config VIDEO_FB_IVTV
config VIDEO_FB_IVTV_FORCE_PAT
bool "force cx23415 framebuffer init with x86 PAT enabled"
depends on VIDEO_FB_IVTV && X86_PAT
- default n
help
With PAT enabled, the cx23415 framebuffer driver does not
utilize write-combined caching on the framebuffer memory.
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index f2b5f27ebacb..8a19654b393a 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -6,7 +6,6 @@
menuconfig V4L_PLATFORM_DRIVERS
bool "V4L platform devices"
depends on MEDIA_CAMERA_SUPPORT
- default n
help
Say Y here to enable support for platform-specific V4L drivers.
@@ -155,7 +154,6 @@ config VIDEO_TI_CAL
depends on SOC_DRA7XX || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select V4L2_FWNODE
- default n
help
Support for the TI CAL (Camera Adaptation Layer) block
found on DRA72X SoC.
@@ -168,7 +166,6 @@ menuconfig V4L_MEM2MEM_DRIVERS
bool "Memory-to-memory multimedia devices"
depends on VIDEO_V4L2
depends on MEDIA_CAMERA_SUPPORT
- default n
help
Say Y here to enable selecting drivers for V4L devices that
use system memory for both source and destination buffers, as opposed
@@ -236,7 +233,6 @@ config VIDEO_MEDIATEK_MDP
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
select VIDEO_MEDIATEK_VPU
- default n
help
It is a v4l2 driver and present in Mediatek MT8173 SoCs.
The driver supports for scaling and color space conversion.
@@ -252,7 +248,6 @@ config VIDEO_MEDIATEK_VCODEC
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
select VIDEO_MEDIATEK_VPU
- default n
help
Mediatek video codec driver provides HW capability to
encode and decode in a range of video formats
@@ -276,7 +271,6 @@ config VIDEO_SAMSUNG_S5P_G2D
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
- default n
help
This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
2d graphics accelerator.
@@ -296,7 +290,6 @@ config VIDEO_SAMSUNG_S5P_MFC
depends on VIDEO_DEV && VIDEO_V4L2
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
- default n
help
MFC 5.1 and 6.x driver for V4L2
@@ -459,7 +452,6 @@ config VIDEO_ROCKCHIP_RGA
depends on ARCH_ROCKCHIP || COMPILE_TEST
select VIDEOBUF2_DMA_SG
select V4L2_MEM2MEM_DEV
- default n
help
This is a v4l2 driver for Rockchip SOC RGA 2d graphics accelerator.
Rockchip RGA is a separate 2D raster graphic acceleration unit.
@@ -477,7 +469,6 @@ config VIDEO_TI_VPE
select VIDEO_TI_VPDMA
select VIDEO_TI_SC
select VIDEO_TI_CSC
- default n
help
Support for the TI VPE(Video Processing Engine) block
found on DRA7XX SoC.
@@ -530,7 +521,6 @@ config VIDEO_VIM2M
depends on VIDEO_DEV && VIDEO_V4L2
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
- default n
help
This is a virtual test device for the memory-to-memory driver
framework.
@@ -542,7 +532,6 @@ endif #V4L_TEST_DRIVERS
menuconfig DVB_PLATFORM_DRIVERS
bool "DVB platform devices"
depends on MEDIA_DIGITAL_TV_SUPPORT
- default n
help
Say Y here to enable support for platform-specific Digital TV drivers.
@@ -678,7 +667,6 @@ endif #CEC_PLATFORM_DRIVERS
menuconfig SDR_PLATFORM_DRIVERS
bool "SDR platform devices"
depends on MEDIA_SDR_SUPPORT
- default n
help
Say Y here to enable support for platform-specific SDR Drivers.
diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h
index 8f7f8efc71a7..c1283fb21bf6 100644
--- a/drivers/media/platform/atmel/atmel-isc-regs.h
+++ b/drivers/media/platform/atmel/atmel-isc-regs.h
@@ -100,13 +100,15 @@
#define ISC_WB_O_RGR 0x00000060
/* ISC White Balance Offset for B, GB Register */
-#define ISC_WB_O_BGR 0x00000064
+#define ISC_WB_O_BGB 0x00000064
/* ISC White Balance Gain for R, GR Register */
#define ISC_WB_G_RGR 0x00000068
/* ISC White Balance Gain for B, GB Register */
-#define ISC_WB_G_BGR 0x0000006c
+#define ISC_WB_G_BGB 0x0000006c
+
+#define ISC_WB_O_ZERO_VAL (1 << 13)
/* ISC Color Filter Array Control Register */
#define ISC_CFA_CTRL 0x00000070
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index 94cb309fdb52..da3b441e7961 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -167,15 +167,22 @@ struct isc_ctrls {
u32 brightness;
u32 contrast;
u8 gamma_index;
+#define ISC_WB_NONE 0
+#define ISC_WB_AUTO 1
+#define ISC_WB_ONETIME 2
u8 awb;
- u32 r_gain;
- u32 b_gain;
+ /* one for each component : GR, R, GB, B */
+ u32 gain[HIST_BAYER];
+ u32 offset[HIST_BAYER];
u32 hist_entry[HIST_ENTRIES];
u32 hist_count[HIST_BAYER];
u8 hist_id;
u8 hist_stat;
+#define HIST_MIN_INDEX 0
+#define HIST_MAX_INDEX 1
+ u32 hist_minmax[HIST_BAYER][2];
};
#define ISC_PIPE_LINE_NODE_NUM 11
@@ -206,9 +213,11 @@ struct isc_device {
struct fmt_config try_config;
struct isc_ctrls ctrls;
+ struct v4l2_ctrl *do_wb_ctrl;
struct work_struct awb_work;
struct mutex lock;
+ spinlock_t awb_lock;
struct regmap_field *pipeline[ISC_PIPE_LINE_NODE_NUM];
@@ -395,6 +404,40 @@ module_param(sensor_preferred, uint, 0644);
MODULE_PARM_DESC(sensor_preferred,
"Sensor is preferred to output the specified format (1-on 0-off), default 1");
+static inline void isc_update_awb_ctrls(struct isc_device *isc)
+{
+ struct isc_ctrls *ctrls = &isc->ctrls;
+
+ regmap_write(isc->regmap, ISC_WB_O_RGR,
+ (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_R])) |
+ ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));
+ regmap_write(isc->regmap, ISC_WB_O_BGB,
+ (ISC_WB_O_ZERO_VAL - (ctrls->offset[ISC_HIS_CFG_MODE_B])) |
+ ((ISC_WB_O_ZERO_VAL - ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16));
+ regmap_write(isc->regmap, ISC_WB_G_RGR,
+ ctrls->gain[ISC_HIS_CFG_MODE_R] |
+ (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16));
+ regmap_write(isc->regmap, ISC_WB_G_BGB,
+ ctrls->gain[ISC_HIS_CFG_MODE_B] |
+ (ctrls->gain[ISC_HIS_CFG_MODE_GB] << 16));
+}
+
+static inline void isc_reset_awb_ctrls(struct isc_device *isc)
+{
+ int c;
+
+ for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {
+ /* gains have a fixed point at 9 decimals */
+ isc->ctrls.gain[c] = 1 << 9;
+ /* offsets are in 2's complements, the value
+ * will be substracted from ISC_WB_O_ZERO_VAL to obtain
+ * 2's complement of a value between 0 and
+ * ISC_WB_O_ZERO_VAL >> 1
+ */
+ isc->ctrls.offset[c] = ISC_WB_O_ZERO_VAL;
+ }
+}
+
static int isc_wait_clk_stable(struct clk_hw *hw)
{
struct isc_clk *isc_clk = to_isc_clk(hw);
@@ -775,7 +818,9 @@ static void isc_start_dma(struct isc_device *isc)
dctrl_dview = isc->config.dctrl_dview;
regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS);
+ spin_lock(&isc->awb_lock);
regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE);
+ spin_unlock(&isc->awb_lock);
}
static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
@@ -797,11 +842,11 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
bay_cfg = isc->config.sd_format->cfa_baycfg;
+ if (ctrls->awb == ISC_WB_NONE)
+ isc_reset_awb_ctrls(isc);
+
regmap_write(regmap, ISC_WB_CFG, bay_cfg);
- regmap_write(regmap, ISC_WB_O_RGR, 0x0);
- regmap_write(regmap, ISC_WB_O_BGR, 0x0);
- regmap_write(regmap, ISC_WB_G_RGR, ctrls->r_gain | (0x1 << 25));
- regmap_write(regmap, ISC_WB_G_BGR, ctrls->b_gain | (0x1 << 25));
+ isc_update_awb_ctrls(isc);
regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL);
@@ -851,13 +896,13 @@ static void isc_set_histogram(struct isc_device *isc, bool enable)
if (enable) {
regmap_write(regmap, ISC_HIS_CFG,
- ISC_HIS_CFG_MODE_R |
+ ISC_HIS_CFG_MODE_GR |
(isc->config.sd_format->cfa_baycfg
<< ISC_HIS_CFG_BAYSEL_SHIFT) |
ISC_HIS_CFG_RAR);
regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN);
regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE);
- ctrls->hist_id = ISC_HIS_CFG_MODE_R;
+ ctrls->hist_id = ISC_HIS_CFG_MODE_GR;
isc_update_profile(isc);
regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
@@ -900,7 +945,7 @@ static int isc_configure(struct isc_device *isc)
isc_set_pipeline(isc, pipeline);
/*
- * The current implemented histogram is available for RAW R, B, GB
+ * The current implemented histogram is available for RAW R, B, GB, GR
* channels. We need to check if sensor is outputting RAW BAYER
*/
if (isc->ctrls.awb &&
@@ -952,6 +997,10 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
+ /* if we streaming from RAW, we can do one-shot white balance adj */
+ if (ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
+ v4l2_ctrl_activate(isc->do_wb_ctrl, true);
+
return 0;
err_configure:
@@ -976,6 +1025,8 @@ static void isc_stop_streaming(struct vb2_queue *vq)
struct isc_buffer *buf;
int ret;
+ v4l2_ctrl_activate(isc->do_wb_ctrl, false);
+
isc->stop = true;
/* Wait until the end of the current frame */
@@ -1436,7 +1487,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
&pad_cfg, &format);
if (ret < 0)
- goto isc_try_fmt_err;
+ goto isc_try_fmt_subdev_err;
v4l2_fill_pix_format(pixfmt, &format.format);
@@ -1451,6 +1502,7 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
isc_try_fmt_err:
v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
+isc_try_fmt_subdev_err:
memset(&isc->try_config, 0, sizeof(isc->try_config));
return ret;
@@ -1475,6 +1527,12 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
return ret;
isc->fmt = *f;
+
+ if (isc->try_config.sd_format && isc->config.sd_format &&
+ isc->try_config.sd_format != isc->config.sd_format) {
+ isc->ctrls.hist_stat = HIST_INIT;
+ isc_reset_awb_ctrls(isc);
+ }
/* make the try configuration active */
isc->config = isc->try_config;
@@ -1758,7 +1816,7 @@ static irqreturn_t isc_interrupt(int irq, void *dev_id)
return ret;
}
-static void isc_hist_count(struct isc_device *isc)
+static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max)
{
struct regmap *regmap = isc->regmap;
struct isc_ctrls *ctrls = &isc->ctrls;
@@ -1766,25 +1824,99 @@ static void isc_hist_count(struct isc_device *isc)
u32 *hist_entry = &ctrls->hist_entry[0];
u32 i;
+ *min = 0;
+ *max = HIST_ENTRIES;
+
regmap_bulk_read(regmap, ISC_HIS_ENTRY, hist_entry, HIST_ENTRIES);
*hist_count = 0;
- for (i = 0; i < HIST_ENTRIES; i++)
+ /*
+ * we deliberately ignore the end of the histogram,
+ * the most white pixels
+ */
+ for (i = 1; i < HIST_ENTRIES; i++) {
+ if (*hist_entry && !*min)
+ *min = i;
+ if (*hist_entry)
+ *max = i;
*hist_count += i * (*hist_entry++);
+ }
+
+ if (!*min)
+ *min = 1;
}
static void isc_wb_update(struct isc_ctrls *ctrls)
{
u32 *hist_count = &ctrls->hist_count[0];
- u64 g_count = (u64)hist_count[ISC_HIS_CFG_MODE_GB] << 9;
- u32 hist_r = hist_count[ISC_HIS_CFG_MODE_R];
- u32 hist_b = hist_count[ISC_HIS_CFG_MODE_B];
+ u32 c, offset[4];
+ u64 avg = 0;
+ /* We compute two gains, stretch gain and grey world gain */
+ u32 s_gain[4], gw_gain[4];
+
+ /*
+ * According to Grey World, we need to set gains for R/B to normalize
+ * them towards the green channel.
+ * Thus we want to keep Green as fixed and adjust only Red/Blue
+ * Compute the average of the both green channels first
+ */
+ avg = (u64)hist_count[ISC_HIS_CFG_MODE_GR] +
+ (u64)hist_count[ISC_HIS_CFG_MODE_GB];
+ avg >>= 1;
- if (hist_r)
- ctrls->r_gain = div_u64(g_count, hist_r);
+ /* Green histogram is null, nothing to do */
+ if (!avg)
+ return;
- if (hist_b)
- ctrls->b_gain = div_u64(g_count, hist_b);
+ for (c = ISC_HIS_CFG_MODE_GR; c <= ISC_HIS_CFG_MODE_B; c++) {
+ /*
+ * the color offset is the minimum value of the histogram.
+ * we stretch this color to the full range by substracting
+ * this value from the color component.
+ */
+ offset[c] = ctrls->hist_minmax[c][HIST_MIN_INDEX];
+ /*
+ * The offset is always at least 1. If the offset is 1, we do
+ * not need to adjust it, so our result must be zero.
+ * the offset is computed in a histogram on 9 bits (0..512)
+ * but the offset in register is based on
+ * 12 bits pipeline (0..4096).
+ * we need to shift with the 3 bits that the histogram is
+ * ignoring
+ */
+ ctrls->offset[c] = (offset[c] - 1) << 3;
+
+ /* the offset is then taken and converted to 2's complements */
+ if (!ctrls->offset[c])
+ ctrls->offset[c] = ISC_WB_O_ZERO_VAL;
+
+ /*
+ * the stretch gain is the total number of histogram bins
+ * divided by the actual range of color component (Max - Min)
+ * If we compute gain like this, the actual color component
+ * will be stretched to the full histogram.
+ * We need to shift 9 bits for precision, we have 9 bits for
+ * decimals
+ */
+ s_gain[c] = (HIST_ENTRIES << 9) /
+ (ctrls->hist_minmax[c][HIST_MAX_INDEX] -
+ ctrls->hist_minmax[c][HIST_MIN_INDEX] + 1);
+
+ /*
+ * Now we have to compute the gain w.r.t. the average.
+ * Add/lose gain to the component towards the average.
+ * If it happens that the component is zero, use the
+ * fixed point value : 1.0 gain.
+ */
+ if (hist_count[c])
+ gw_gain[c] = div_u64(avg << 9, hist_count[c]);
+ else
+ gw_gain[c] = 1 << 9;
+
+ /* multiply both gains and adjust for decimals */
+ ctrls->gain[c] = s_gain[c] * gw_gain[c];
+ ctrls->gain[c] >>= 9;
+ }
}
static void isc_awb_work(struct work_struct *w)
@@ -1795,27 +1927,66 @@ static void isc_awb_work(struct work_struct *w)
struct isc_ctrls *ctrls = &isc->ctrls;
u32 hist_id = ctrls->hist_id;
u32 baysel;
+ unsigned long flags;
+ u32 min, max;
+
+ /* streaming is not active anymore */
+ if (isc->stop)
+ return;
if (ctrls->hist_stat != HIST_ENABLED)
return;
- isc_hist_count(isc);
+ isc_hist_count(isc, &min, &max);
+ ctrls->hist_minmax[hist_id][HIST_MIN_INDEX] = min;
+ ctrls->hist_minmax[hist_id][HIST_MAX_INDEX] = max;
if (hist_id != ISC_HIS_CFG_MODE_B) {
hist_id++;
} else {
isc_wb_update(ctrls);
- hist_id = ISC_HIS_CFG_MODE_R;
+ hist_id = ISC_HIS_CFG_MODE_GR;
}
ctrls->hist_id = hist_id;
baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
+ /* if no more auto white balance, reset controls. */
+ if (ctrls->awb == ISC_WB_NONE)
+ isc_reset_awb_ctrls(isc);
+
pm_runtime_get_sync(isc->dev);
+ /*
+ * only update if we have all the required histograms and controls
+ * if awb has been disabled, we need to reset registers as well.
+ */
+ if (hist_id == ISC_HIS_CFG_MODE_GR || ctrls->awb == ISC_WB_NONE) {
+ /*
+ * It may happen that DMA Done IRQ will trigger while we are
+ * updating white balance registers here.
+ * In that case, only parts of the controls have been updated.
+ * We can avoid that by locking the section.
+ */
+ spin_lock_irqsave(&isc->awb_lock, flags);
+ isc_update_awb_ctrls(isc);
+ spin_unlock_irqrestore(&isc->awb_lock, flags);
+
+ /*
+ * if we are doing just the one time white balance adjustment,
+ * we are basically done.
+ */
+ if (ctrls->awb == ISC_WB_ONETIME) {
+ v4l2_info(&isc->v4l2_dev,
+ "Completed one time white-balance adjustment.\n");
+ ctrls->awb = ISC_WB_NONE;
+ }
+ }
regmap_write(regmap, ISC_HIS_CFG, hist_id | baysel | ISC_HIS_CFG_RAR);
isc_update_profile(isc);
- regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
+ /* if awb has been disabled, we don't need to start another histogram */
+ if (ctrls->awb)
+ regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
pm_runtime_put_sync(isc->dev);
}
@@ -1826,6 +1997,9 @@ static int isc_s_ctrl(struct v4l2_ctrl *ctrl)
struct isc_device, ctrls.handler);
struct isc_ctrls *ctrls = &isc->ctrls;
+ if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+ return 0;
+
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrls->brightness = ctrl->val & ISC_CBC_BRIGHT_MASK;
@@ -1837,11 +2011,33 @@ static int isc_s_ctrl(struct v4l2_ctrl *ctrl)
ctrls->gamma_index = ctrl->val;
break;
case V4L2_CID_AUTO_WHITE_BALANCE:
- ctrls->awb = ctrl->val;
- if (ctrls->hist_stat != HIST_ENABLED) {
- ctrls->r_gain = 0x1 << 9;
- ctrls->b_gain = 0x1 << 9;
- }
+ if (ctrl->val == 1)
+ ctrls->awb = ISC_WB_AUTO;
+ else
+ ctrls->awb = ISC_WB_NONE;
+
+ /* we did not configure ISC yet */
+ if (!isc->config.sd_format)
+ break;
+
+ if (ctrls->hist_stat != HIST_ENABLED)
+ isc_reset_awb_ctrls(isc);
+
+ if (isc->ctrls.awb == ISC_WB_AUTO &&
+ vb2_is_streaming(&isc->vb2_vidq) &&
+ ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
+ isc_set_histogram(isc, true);
+
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ /* if AWB is enabled, do nothing */
+ if (ctrls->awb == ISC_WB_AUTO)
+ return 0;
+
+ ctrls->awb = ISC_WB_ONETIME;
+ isc_set_histogram(isc, true);
+ v4l2_dbg(1, debug, &isc->v4l2_dev,
+ "One time white-balance started.\n");
break;
default:
return -EINVAL;
@@ -1862,16 +2058,26 @@ static int isc_ctrl_init(struct isc_device *isc)
int ret;
ctrls->hist_stat = HIST_INIT;
+ isc_reset_awb_ctrls(isc);
- ret = v4l2_ctrl_handler_init(hdl, 4);
+ ret = v4l2_ctrl_handler_init(hdl, 5);
if (ret < 0)
return ret;
+ ctrls->brightness = 0;
+ ctrls->contrast = 256;
+
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+ /* do_white_balance is a button, so min,max,step,default are ignored */
+ isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_DO_WHITE_BALANCE,
+ 0, 0, 0, 0);
+
+ v4l2_ctrl_activate(isc->do_wb_ctrl, false);
+
v4l2_ctrl_handler_setup(hdl);
return 0;
@@ -2034,6 +2240,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
/* Init video dma queues */
INIT_LIST_HEAD(&isc->dma_queue);
spin_lock_init(&isc->dma_queue_lock);
+ spin_lock_init(&isc->awb_lock);
ret = isc_formats_init(isc);
if (ret < 0) {
diff --git a/drivers/media/platform/cec-gpio/cec-gpio.c b/drivers/media/platform/cec-gpio/cec-gpio.c
index d2861749d640..5b17d3a31896 100644
--- a/drivers/media/platform/cec-gpio/cec-gpio.c
+++ b/drivers/media/platform/cec-gpio/cec-gpio.c
@@ -17,7 +17,6 @@ struct cec_gpio {
struct gpio_desc *cec_gpio;
int cec_irq;
bool cec_is_low;
- bool cec_have_irq;
struct gpio_desc *hpd_gpio;
int hpd_irq;
@@ -55,9 +54,6 @@ static void cec_gpio_low(struct cec_adapter *adap)
if (cec->cec_is_low)
return;
- if (WARN_ON_ONCE(cec->cec_have_irq))
- free_irq(cec->cec_irq, cec);
- cec->cec_have_irq = false;
cec->cec_is_low = true;
gpiod_set_value(cec->cec_gpio, 0);
}
@@ -114,14 +110,7 @@ static bool cec_gpio_enable_irq(struct cec_adapter *adap)
{
struct cec_gpio *cec = cec_get_drvdata(adap);
- if (cec->cec_have_irq)
- return true;
-
- if (request_irq(cec->cec_irq, cec_gpio_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- adap->name, cec))
- return false;
- cec->cec_have_irq = true;
+ enable_irq(cec->cec_irq);
return true;
}
@@ -129,9 +118,7 @@ static void cec_gpio_disable_irq(struct cec_adapter *adap)
{
struct cec_gpio *cec = cec_get_drvdata(adap);
- if (cec->cec_have_irq)
- free_irq(cec->cec_irq, cec);
- cec->cec_have_irq = false;
+ disable_irq(cec->cec_irq);
}
static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file)
@@ -139,8 +126,7 @@ static void cec_gpio_status(struct cec_adapter *adap, struct seq_file *file)
struct cec_gpio *cec = cec_get_drvdata(adap);
seq_printf(file, "mode: %s\n", cec->cec_is_low ? "low-drive" : "read");
- if (cec->cec_have_irq)
- seq_printf(file, "using irq: %d\n", cec->cec_irq);
+ seq_printf(file, "using irq: %d\n", cec->cec_irq);
if (cec->hpd_gpio)
seq_printf(file, "hpd: %s\n",
cec->hpd_is_high ? "high" : "low");
@@ -215,6 +201,14 @@ static int cec_gpio_probe(struct platform_device *pdev)
if (IS_ERR(cec->adap))
return PTR_ERR(cec->adap);
+ ret = devm_request_irq(dev, cec->cec_irq, cec_gpio_irq_handler,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ cec->adap->name, cec);
+ if (ret)
+ return ret;
+
+ cec_gpio_disable_irq(cec->adap);
+
if (cec->hpd_gpio) {
cec->hpd_irq = gpiod_to_irq(cec->hpd_gpio);
ret = devm_request_threaded_irq(dev, cec->hpd_irq,
diff --git a/drivers/media/platform/coda/Makefile b/drivers/media/platform/coda/Makefile
index f13adacd924e..e17875e4343c 100644
--- a/drivers/media/platform/coda/Makefile
+++ b/drivers/media/platform/coda/Makefile
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-ccflags-y += -I$(src)
coda-objs := coda-common.o coda-bit.o coda-gdi.o coda-h264.o coda-jpeg.o
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index eaa86737fa04..d774a5aaa422 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -1456,6 +1456,13 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
return 0;
}
+static char coda_frame_type_char(u32 flags)
+{
+ return (flags & V4L2_BUF_FLAG_KEYFRAME) ? 'I' :
+ (flags & V4L2_BUF_FLAG_PFRAME) ? 'P' :
+ (flags & V4L2_BUF_FLAG_BFRAME) ? 'B' : '?';
+}
+
static void coda_finish_encode(struct coda_ctx *ctx)
{
struct vb2_v4l2_buffer *src_buf, *dst_buf;
@@ -1512,8 +1519,7 @@ static void coda_finish_encode(struct coda_ctx *ctx)
ctx->gopcounter = ctx->params.gop_size - 1;
coda_dbg(1, ctx, "job finished: encoded %c frame (%d)\n",
- (dst_buf->flags & V4L2_BUF_FLAG_KEYFRAME) ? 'I' : 'P',
- dst_buf->sequence);
+ coda_frame_type_char(dst_buf->flags), dst_buf->sequence);
}
static void coda_seq_end_work(struct work_struct *work)
@@ -1808,6 +1814,17 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
(top_bottom & 0x3ff);
}
+ if (dev->devtype->product != CODA_DX6) {
+ u8 profile, level;
+
+ val = coda_read(dev, CODA7_RET_DEC_SEQ_HEADER_REPORT);
+ profile = val & 0xff;
+ level = (val >> 8) & 0x7f;
+
+ if (profile || level)
+ coda_update_profile_level_ctrls(ctx, profile, level);
+ }
+
ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "failed to allocate framebuffers\n");
@@ -2240,13 +2257,36 @@ static void coda_finish_decode(struct coda_ctx *ctx)
else
coda_m2m_buf_done(ctx, dst_buf, VB2_BUF_STATE_DONE);
- coda_dbg(1, ctx, "job finished: decoded %c frame (%u/%u)\n",
- (dst_buf->flags & V4L2_BUF_FLAG_KEYFRAME) ? 'I' :
- ((dst_buf->flags & V4L2_BUF_FLAG_PFRAME) ? 'P' : 'B'),
- dst_buf->sequence, ctx->qsequence);
+ if (decoded_idx >= 0 &&
+ decoded_idx < ctx->num_internal_frames) {
+ coda_dbg(1, ctx, "job finished: decoded %c frame %u, returned %c frame %u (%u/%u)%s\n",
+ coda_frame_type_char(ctx->frame_types[decoded_idx]),
+ ctx->frame_metas[decoded_idx].sequence,
+ coda_frame_type_char(dst_buf->flags),
+ ctx->frame_metas[ctx->display_idx].sequence,
+ dst_buf->sequence, ctx->qsequence,
+ (dst_buf->flags & V4L2_BUF_FLAG_LAST) ?
+ " (last)" : "");
+ } else {
+ coda_dbg(1, ctx, "job finished: no frame decoded (%d), returned %c frame %u (%u/%u)%s\n",
+ decoded_idx,
+ coda_frame_type_char(dst_buf->flags),
+ ctx->frame_metas[ctx->display_idx].sequence,
+ dst_buf->sequence, ctx->qsequence,
+ (dst_buf->flags & V4L2_BUF_FLAG_LAST) ?
+ " (last)" : "");
+ }
} else {
- coda_dbg(1, ctx, "job finished: no frame decoded (%u/%u)\n",
- ctx->osequence, ctx->qsequence);
+ if (decoded_idx >= 0 &&
+ decoded_idx < ctx->num_internal_frames) {
+ coda_dbg(1, ctx, "job finished: decoded %c frame %u, no frame returned (%d)\n",
+ coda_frame_type_char(ctx->frame_types[decoded_idx]),
+ ctx->frame_metas[decoded_idx].sequence,
+ ctx->display_idx);
+ } else {
+ coda_dbg(1, ctx, "job finished: no frame decoded (%d) or returned (%d)\n",
+ decoded_idx, ctx->display_idx);
+ }
}
/* The rotator will copy the current display frame next time */
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 1d96cca61547..1856b782fdde 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(enable_bwb, "Enable BWB unit for decoding, may crash on certain
void coda_write(struct coda_dev *dev, u32 data, u32 reg)
{
- v4l2_dbg(2, coda_debug, &dev->v4l2_dev,
+ v4l2_dbg(3, coda_debug, &dev->v4l2_dev,
"%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
writel(data, dev->regs_base + reg);
}
@@ -88,7 +88,7 @@ unsigned int coda_read(struct coda_dev *dev, u32 reg)
u32 data;
data = readl(dev->regs_base + reg);
- v4l2_dbg(2, coda_debug, &dev->v4l2_dev,
+ v4l2_dbg(3, coda_debug, &dev->v4l2_dev,
"%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
return data;
}
@@ -1416,7 +1416,7 @@ static int coda_job_ready(void *m2m_priv)
return 0;
}
- coda_dbg(1, ctx, "job ready\n");
+ coda_dbg(2, ctx, "job ready\n");
return 1;
}
@@ -1567,42 +1567,53 @@ static void coda_update_menu_ctrl(struct v4l2_ctrl *ctrl, int value)
v4l2_ctrl_unlock(ctrl);
}
-static void coda_update_h264_profile_ctrl(struct coda_ctx *ctx)
+void coda_update_profile_level_ctrls(struct coda_ctx *ctx, u8 profile_idc,
+ u8 level_idc)
{
const char * const *profile_names;
+ const char * const *level_names;
+ struct v4l2_ctrl *profile_ctrl;
+ struct v4l2_ctrl *level_ctrl;
+ const char *codec_name;
+ u32 profile_cid;
+ u32 level_cid;
int profile;
+ int level;
- profile = coda_h264_profile(ctx->params.h264_profile_idc);
- if (profile < 0) {
- v4l2_warn(&ctx->dev->v4l2_dev, "Invalid H264 Profile: %u\n",
- ctx->params.h264_profile_idc);
+ switch (ctx->codec->src_fourcc) {
+ case V4L2_PIX_FMT_H264:
+ codec_name = "H264";
+ profile_cid = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ level_cid = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ profile_ctrl = ctx->h264_profile_ctrl;
+ level_ctrl = ctx->h264_level_ctrl;
+ profile = coda_h264_profile(profile_idc);
+ level = coda_h264_level(level_idc);
+ break;
+ default:
return;
}
- coda_update_menu_ctrl(ctx->h264_profile_ctrl, profile);
+ profile_names = v4l2_ctrl_get_menu(profile_cid);
+ level_names = v4l2_ctrl_get_menu(level_cid);
- profile_names = v4l2_ctrl_get_menu(V4L2_CID_MPEG_VIDEO_H264_PROFILE);
-
- coda_dbg(1, ctx, "Parsed H264 Profile: %s\n", profile_names[profile]);
-}
-
-static void coda_update_h264_level_ctrl(struct coda_ctx *ctx)
-{
- const char * const *level_names;
- int level;
+ if (profile < 0) {
+ v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s profile: %u\n",
+ codec_name, profile_idc);
+ } else {
+ coda_dbg(1, ctx, "Parsed %s profile: %s\n", codec_name,
+ profile_names[profile]);
+ coda_update_menu_ctrl(profile_ctrl, profile);
+ }
- level = coda_h264_level(ctx->params.h264_level_idc);
if (level < 0) {
- v4l2_warn(&ctx->dev->v4l2_dev, "Invalid H264 Level: %u\n",
- ctx->params.h264_level_idc);
- return;
+ v4l2_warn(&ctx->dev->v4l2_dev, "Invalid %s level: %u\n",
+ codec_name, level_idc);
+ } else {
+ coda_dbg(1, ctx, "Parsed %s level: %s\n", codec_name,
+ level_names[level]);
+ coda_update_menu_ctrl(level_ctrl, level);
}
-
- coda_update_menu_ctrl(ctx->h264_level_ctrl, level);
-
- level_names = v4l2_ctrl_get_menu(V4L2_CID_MPEG_VIDEO_H264_LEVEL);
-
- coda_dbg(1, ctx, "Parsed H264 Level: %s\n", level_names[level]);
}
static void coda_buf_queue(struct vb2_buffer *vb)
@@ -1635,8 +1646,9 @@ static void coda_buf_queue(struct vb2_buffer *vb)
*/
if (!ctx->params.h264_profile_idc) {
coda_sps_parse_profile(ctx, vb);
- coda_update_h264_profile_ctrl(ctx);
- coda_update_h264_level_ctrl(ctx);
+ coda_update_profile_level_ctrls(ctx,
+ ctx->params.h264_profile_idc,
+ ctx->params.h264_level_idc);
}
}
@@ -1857,11 +1869,16 @@ static const struct vb2_ops coda_qops = {
static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
{
+ const char * const *val_names = v4l2_ctrl_get_menu(ctrl->id);
struct coda_ctx *ctx =
container_of(ctrl->handler, struct coda_ctx, ctrls);
- coda_dbg(1, ctx, "s_ctrl: id = 0x%x, name = \"%s\", val = %d\n",
- ctrl->id, ctrl->name, ctrl->val);
+ if (val_names)
+ coda_dbg(2, ctx, "s_ctrl: id = 0x%x, name = \"%s\", val = %d (\"%s\")\n",
+ ctrl->id, ctrl->name, ctrl->val, val_names[ctrl->val]);
+ else
+ coda_dbg(2, ctx, "s_ctrl: id = 0x%x, name = \"%s\", val = %d\n",
+ ctrl->id, ctrl->name, ctrl->val);
switch (ctrl->id) {
case V4L2_CID_HFLIP:
diff --git a/drivers/media/platform/coda/coda-h264.c b/drivers/media/platform/coda/coda-h264.c
index 635356a839cf..6da82d13eb21 100644
--- a/drivers/media/platform/coda/coda-h264.c
+++ b/drivers/media/platform/coda/coda-h264.c
@@ -14,7 +14,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/videodev2.h>
-#include <coda.h>
+
+#include "coda.h"
static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 };
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 31c80bda2c0b..1c822dfdb3ce 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -328,6 +328,9 @@ int coda_sps_parse_profile(struct coda_ctx *ctx, struct vb2_buffer *vb);
int coda_h264_sps_fixup(struct coda_ctx *ctx, int width, int height, char *buf,
int *size, int max_size);
+void coda_update_profile_level_ctrls(struct coda_ctx *ctx, u8 profile_idc,
+ u8 level_idc);
+
bool coda_jpeg_check_buffer(struct coda_ctx *ctx, struct vb2_buffer *vb);
int coda_jpeg_write_tables(struct coda_ctx *ctx);
void coda_set_jpeg_compression_quality(struct coda_ctx *ctx, int quality);
diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h
index e675e38f3475..35cec9f83085 100644
--- a/drivers/media/platform/coda/coda_regs.h
+++ b/drivers/media/platform/coda/coda_regs.h
@@ -181,7 +181,7 @@
#define CODA_RET_DEC_SEQ_FRATE_DR 0x1e8
#define CODA_RET_DEC_SEQ_JPG_PARA 0x1e4
#define CODA_RET_DEC_SEQ_JPG_THUMB_IND 0x1e8
-#define CODA9_RET_DEC_SEQ_HEADER_REPORT 0x1ec
+#define CODA7_RET_DEC_SEQ_HEADER_REPORT 0x1ec
/* Decoder Picture Run */
#define CODA_CMD_DEC_PIC_ROT_MODE 0x180
diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h
index a672bfc4c6ba..6cf58237fff2 100644
--- a/drivers/media/platform/coda/trace.h
+++ b/drivers/media/platform/coda/trace.h
@@ -157,7 +157,7 @@ DEFINE_EVENT(coda_buf_meta_class, coda_dec_rot_done,
#endif /* __CODA_TRACE_H__ */
#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_PATH ../../drivers/media/platform/coda
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE trace
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c
index 19cf6853411e..b4ff3f1961a1 100644
--- a/drivers/media/platform/davinci/vpss.c
+++ b/drivers/media/platform/davinci/vpss.c
@@ -507,9 +507,9 @@ static struct platform_driver vpss_driver = {
static void vpss_exit(void)
{
+ platform_driver_unregister(&vpss_driver);
iounmap(oper_cfg.vpss_regs_base2);
release_mem_region(VPSS_CLK_CTRL, 4);
- platform_driver_unregister(&vpss_driver);
}
static int __init vpss_init(void)
@@ -518,6 +518,11 @@ static int __init vpss_init(void)
return -EBUSY;
oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4);
+ if (unlikely(!oper_cfg.vpss_regs_base2)) {
+ release_mem_region(VPSS_CLK_CTRL, 4);
+ return -ENOMEM;
+ }
+
writel(VPSS_CLK_CTRL_VENCCLKEN |
VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 463f2d84553e..d1d5041cdae5 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -449,6 +449,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
else
pd->fimc_bus_type = pd->sensor_bus_type;
+ of_node_put(np);
if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) {
of_node_put(rem);
@@ -474,7 +475,8 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
{
struct device_node *parent = fmd->pdev->dev.of_node;
- struct device_node *node, *ports;
+ struct device_node *ports = NULL;
+ struct device_node *node;
int index = 0;
int ret;
@@ -523,12 +525,14 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
}
index++;
}
+ of_node_put(ports);
rpm_put:
pm_runtime_put(fmd->pmf);
return 0;
cleanup:
+ of_node_put(ports);
v4l2_async_notifier_cleanup(&fmd->subdev_notifier);
pm_runtime_put(fmd->pmf);
return ret;
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index f1b301810260..040fe9501415 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -200,7 +200,6 @@ struct mcam_vb_buffer {
struct list_head queue;
struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
dma_addr_t dma_desc_pa; /* Descriptor physical address */
- int dma_desc_nent; /* Number of mapped descriptors */
};
static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_v4l2_buffer *vb)
@@ -608,9 +607,11 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
static void mcam_sg_next_buffer(struct mcam_camera *cam)
{
struct mcam_vb_buffer *buf;
+ struct sg_table *sg_table;
buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
list_del_init(&buf->queue);
+ sg_table = vb2_dma_sg_plane_desc(&buf->vb_buf.vb2_buf, 0);
/*
* Very Bad Not Good Things happen if you don't clear
* C1_DESC_ENA before making any descriptor changes.
@@ -618,7 +619,7 @@ static void mcam_sg_next_buffer(struct mcam_camera *cam)
mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
mcam_reg_write(cam, REG_DESC_LEN_Y,
- buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
+ sg_table->nents * sizeof(struct mcam_dma_desc));
mcam_reg_write(cam, REG_DESC_LEN_U, 0);
mcam_reg_write(cam, REG_DESC_LEN_V, 0);
mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
@@ -791,12 +792,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
* Make sure it knows we want to use hsync/vsync.
*/
mcam_reg_write_mask(cam, REG_CTRL0, C0_SIF_HVSYNC, C0_SIFM_MASK);
- /*
- * This field controls the generation of EOF(DVP only)
- */
- if (cam->bus_type != V4L2_MBUS_CSI2_DPHY)
- mcam_reg_set_bit(cam, REG_CTRL0,
- C0_EOF_VSYNC | C0_VEDGE_CTRL);
}
diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig
index 08a606a5adff..1a99dff21ca0 100644
--- a/drivers/media/platform/omap/Kconfig
+++ b/drivers/media/platform/omap/Kconfig
@@ -14,6 +14,5 @@ config VIDEO_OMAP2_VOUT
select VIDEOBUF_DMA_CONTIG
select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
select FRAME_VECTOR
- default n
help
V4L2 Display driver support for OMAP2/3 based boards.
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 739366744e0f..435c7b68bbed 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -455,7 +455,7 @@ static const struct venus_resources msm8996_res = {
.reg_tbl_size = ARRAY_SIZE(msm8996_reg_preset),
.clks = {"core", "iface", "bus", "mbus" },
.clks_num = 4,
- .max_load = 3110400, /* 4096x2160@90 */
+ .max_load = 2563200,
.hfi_version = HFI_VERSION_3XX,
.vmem_id = VIDC_RESOURCE_NONE,
.vmem_size = 0,
@@ -478,7 +478,7 @@ static const struct venus_resources sdm845_res = {
.freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
.clks = {"core", "iface", "bus" },
.clks_num = 3,
- .max_load = 2563200,
+ .max_load = 3110400, /* 4096x2160@90 */
.hfi_version = HFI_VERSION_4XX,
.vmem_id = VIDC_RESOURCE_NONE,
.vmem_size = 0,
diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c
index 6cfa8021721e..f81449b400c4 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -87,11 +87,11 @@ static int venus_load_fw(struct venus_core *core, const char *fwname,
ret = of_address_to_resource(node, 0, &r);
if (ret)
- return ret;
+ goto err_put_node;
ret = request_firmware(&mdt, fwname, dev);
if (ret < 0)
- return ret;
+ goto err_put_node;
fw_size = qcom_mdt_get_size(mdt);
if (fw_size < 0) {
@@ -125,6 +125,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname,
memunmap(mem_va);
err_release_fw:
release_firmware(mdt);
+err_put_node:
+ of_node_put(node);
return ret;
}
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index 5cad601d4c57..86105de81af2 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -467,6 +467,13 @@ static bool is_dynamic_bufmode(struct venus_inst *inst)
struct venus_core *core = inst->core;
struct venus_caps *caps;
+ /*
+ * v4 doesn't send BUFFER_ALLOC_MODE_SUPPORTED property and supports
+ * dynamic buffer mode by default for HFI_BUFFER_OUTPUT/OUTPUT2.
+ */
+ if (IS_V4(core))
+ return true;
+
caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
if (!caps)
return false;
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
index 87a441488e15..faf1ca0d0db4 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -1214,6 +1214,8 @@ pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
break;
}
case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
+ case HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER:
+ case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE:
/* not implemented on Venus 4xx */
return -ENOTSUPP;
default:
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c
index ac1e1d26f341..bd4538accf13 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -117,6 +117,9 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
ctr->profile.h264 = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
+ ctr->profile.hevc = ctrl->val;
+ break;
case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
ctr->profile.vpx = ctrl->val;
break;
@@ -126,6 +129,9 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
ctr->level.h264 = ctrl->val;
break;
+ case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
+ ctr->level.hevc = ctrl->val;
+ break;
case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
ctr->h264_i_qp = ctrl->val;
break;
@@ -217,7 +223,7 @@ int venc_ctrl_init(struct venus_inst *inst)
{
int ret;
- ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 28);
+ ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 30);
if (ret)
return ret;
@@ -246,6 +252,19 @@ int venc_ctrl_init(struct venus_inst *inst)
0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+ ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+ (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+ (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)),
+ V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
+
+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+ V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+ V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+ 0, V4L2_MPEG_VIDEO_HEVC_LEVEL_1);
+
+ v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
V4L2_CID_MPEG_VIDEO_H264_PROFILE,
V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
diff --git a/drivers/media/platform/vicodec/Kconfig b/drivers/media/platform/vicodec/Kconfig
index 36bb0e934252..89456665cb16 100644
--- a/drivers/media/platform/vicodec/Kconfig
+++ b/drivers/media/platform/vicodec/Kconfig
@@ -4,7 +4,6 @@ config VIDEO_VICODEC
depends on VIDEO_DEV && VIDEO_V4L2
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
- default n
help
Driver for a Virtual Codec
diff --git a/drivers/media/platform/vimc/Kconfig b/drivers/media/platform/vimc/Kconfig
index beba6acce593..bd221d3e1a4a 100644
--- a/drivers/media/platform/vimc/Kconfig
+++ b/drivers/media/platform/vimc/Kconfig
@@ -4,7 +4,6 @@ config VIDEO_VIMC
depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select VIDEOBUF2_VMALLOC
select VIDEO_V4L2_TPG
- default n
help
Skeleton driver for Virtual Media Controller
diff --git a/drivers/media/platform/vivid/Kconfig b/drivers/media/platform/vivid/Kconfig
index b172bcc11758..e2ff06edfa93 100644
--- a/drivers/media/platform/vivid/Kconfig
+++ b/drivers/media/platform/vivid/Kconfig
@@ -11,7 +11,6 @@ config VIDEO_VIVID
select VIDEOBUF2_VMALLOC
select VIDEOBUF2_DMA_CONTIG
select VIDEO_V4L2_TPG
- default n
help
Enables a virtual video driver. This driver emulates a webcam,
TV, S-Video and HDMI capture hardware, including VBI support for
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 4b41687b2bde..eb79d99787bd 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -233,7 +233,6 @@ source "drivers/media/radio/wl128x/Kconfig"
menuconfig V4L_RADIO_ISA_DRIVERS
bool "ISA radio devices"
depends on ISA || COMPILE_TEST
- default n
help
Say Y here to enable support for these ISA drivers.
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
index 66334e8d63ba..c58f2d38a458 100644
--- a/drivers/media/rc/ir-spi.c
+++ b/drivers/media/rc/ir-spi.c
@@ -161,6 +161,7 @@ static const struct of_device_id ir_spi_of_match[] = {
{ .compatible = "ir-spi-led" },
{},
};
+MODULE_DEVICE_TABLE(of, ir_spi_of_match);
static struct spi_driver ir_spi_driver = {
.probe = ir_spi_probe,
diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c
index 9914c83fecb9..02914da8cce5 100644
--- a/drivers/media/rc/meson-ir.c
+++ b/drivers/media/rc/meson-ir.c
@@ -1,14 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Driver for Amlogic Meson IR remote receiver
*
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/device.h>
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index be5fd129d728..13da4c5c7d17 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1502,7 +1502,7 @@ static ssize_t store_wakeup_protocols(struct device *device,
const char *buf, size_t len)
{
struct rc_dev *dev = to_rc_dev(device);
- enum rc_proto protocol;
+ enum rc_proto protocol = RC_PROTO_UNKNOWN;
ssize_t rc;
u64 allowed;
int i;
@@ -1511,9 +1511,7 @@ static ssize_t store_wakeup_protocols(struct device *device,
allowed = dev->allowed_wakeup_protocols;
- if (sysfs_streq(buf, "none")) {
- protocol = RC_PROTO_UNKNOWN;
- } else {
+ if (!sysfs_streq(buf, "none")) {
for (i = 0; i < ARRAY_SIZE(protocols); i++) {
if ((allowed & (1ULL << i)) &&
sysfs_streq(buf, protocols[i].name)) {
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig
index ba464efdab03..08386abb9bbc 100644
--- a/drivers/media/spi/Kconfig
+++ b/drivers/media/spi/Kconfig
@@ -2,7 +2,7 @@
if VIDEO_V4L2
menu "SPI helper chips"
- visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
+ visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
config VIDEO_GS1662
tristate "Gennum Serializers video"
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 72805e5abc68..a7108e575e9b 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -16,7 +16,7 @@ config MEDIA_TUNER
select MEDIA_TUNER_MC44S803 if MEDIA_SUBDRV_AUTOSELECT
menu "Customize TV tuners"
- visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
+ visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST || EXPERT
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT
config MEDIA_TUNER_SIMPLE
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 925a80437822..e306d5d5bebb 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -729,6 +729,12 @@ static int au0828_usb_probe(struct usb_interface *interface,
/* Setup */
au0828_card_setup(dev);
+ /*
+ * Store the pointer to the au0828_dev so it can be accessed in
+ * au0828_usb_disconnect
+ */
+ usb_set_intfdata(interface, dev);
+
/* Analog TV */
retval = au0828_analog_register(dev, interface);
if (retval) {
@@ -747,12 +753,6 @@ static int au0828_usb_probe(struct usb_interface *interface,
/* Remote controller */
au0828_rc_register(dev);
- /*
- * Store the pointer to the au0828_dev so it can be accessed in
- * au0828_usb_disconnect
- */
- usb_set_intfdata(interface, dev);
-
pr_info("Registered device AU0828 [%s]\n",
dev->board.name == NULL ? "Unset" : dev->board.name);
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index de52309eaaab..3afd18733614 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -107,8 +107,6 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen);
exit:
mutex_unlock(&d->usb_mutex);
- if (ret < 0)
- dev_dbg(&intf->dev, "failed=%d\n", ret);
return ret;
}
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
index 91729a39a306..7e817ea506c6 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
@@ -24,14 +24,19 @@ static int dvb_usb_v2_generic_io(struct dvb_usb_device *d,
ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
&actual_length, 2000);
- if (ret < 0)
+ if (ret) {
dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
KBUILD_MODNAME, ret);
- else
- ret = actual_length != wlen ? -EIO : 0;
+ return ret;
+ }
+ if (actual_length != wlen) {
+ dev_err(&d->udev->dev, "%s: usb_bulk_msg() write length=%d, actual=%d\n",
+ KBUILD_MODNAME, wlen, actual_length);
+ return -EIO;
+ }
- /* an answer is expected, and no error before */
- if (!ret && rbuf && rlen) {
+ /* an answer is expected */
+ if (rbuf && rlen) {
if (d->props->generic_bulk_ctrl_delay)
usleep_range(d->props->generic_bulk_ctrl_delay,
d->props->generic_bulk_ctrl_delay
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index ae0814dd202a..3ff9833597e5 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -100,8 +100,6 @@ static int dvbsky_gpio_ctrl(struct dvb_usb_device *d, u8 gport, u8 value)
obuf[1] = gport;
obuf[2] = value;
ret = dvbsky_usb_generic_rw(d, obuf, 3, ibuf, 1);
- if (ret)
- dev_err(&d->udev->dev, "failed=%d\n", ret);
return ret;
}
@@ -139,8 +137,6 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
obuf[3] = msg[0].addr;
ret = dvbsky_usb_generic_rw(d, obuf, 4,
ibuf, msg[0].len + 1);
- if (ret)
- dev_err(&d->udev->dev, "failed=%d\n", ret);
if (!ret)
memcpy(msg[0].buf, &ibuf[1], msg[0].len);
} else {
@@ -151,8 +147,6 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
memcpy(&obuf[3], msg[0].buf, msg[0].len);
ret = dvbsky_usb_generic_rw(d, obuf,
msg[0].len + 3, ibuf, 1);
- if (ret)
- dev_err(&d->udev->dev, "failed=%d\n", ret);
}
} else {
if ((msg[0].len > 60) || (msg[1].len > 60)) {
@@ -170,9 +164,6 @@ static int dvbsky_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
memcpy(&obuf[4], msg[0].buf, msg[0].len);
ret = dvbsky_usb_generic_rw(d, obuf,
msg[0].len + 4, ibuf, msg[1].len + 1);
- if (ret)
- dev_err(&d->udev->dev, "failed=%d\n", ret);
-
if (!ret)
memcpy(msg[1].buf, &ibuf[1], msg[1].len);
}
@@ -201,8 +192,6 @@ static int dvbsky_rc_query(struct dvb_usb_device *d)
obuf[0] = 0x10;
ret = dvbsky_usb_generic_rw(d, obuf, 1, ibuf, 2);
- if (ret)
- dev_err(&d->udev->dev, "failed=%d\n", ret);
if (ret == 0)
code = (ibuf[0] << 8) | ibuf[1];
if (code != 0xffff) {
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
index 99951e02a880..dd063a736df5 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -287,12 +287,15 @@ EXPORT_SYMBOL(dvb_usb_device_init);
void dvb_usb_device_exit(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
- const char *name = "generic DVB-USB module";
+ const char *default_name = "generic DVB-USB module";
+ char name[40];
usb_set_intfdata(intf, NULL);
if (d != NULL && d->desc != NULL) {
- name = d->desc->name;
+ strscpy(name, d->desc->name, sizeof(name));
dvb_usb_exit(d);
+ } else {
+ strscpy(name, default_name, sizeof(name));
}
info("%s successfully deinitialized and disconnected.", name);
diff --git a/drivers/media/usb/s2255/Kconfig b/drivers/media/usb/s2255/Kconfig
index e0e3c0ba3f23..e4a0c914d9c3 100644
--- a/drivers/media/usb/s2255/Kconfig
+++ b/drivers/media/usb/s2255/Kconfig
@@ -3,7 +3,6 @@ config USB_S2255
tristate "USB Sensoray 2255 video capture device"
depends on VIDEO_V4L2
select VIDEOBUF2_VMALLOC
- default n
help
Say Y here if you want support for the Sensoray 2255 USB device.
This driver can be compiled as a module, called s2255drv.
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 8b9d4b3ec10e..7c5f62f196e5 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -13,7 +13,6 @@ config VIDEO_V4L2
config VIDEO_ADV_DEBUG
bool "Enable advanced debug functionality on V4L2 drivers"
- default n
help
Say Y here to enable advanced debugging functionality on some
V4L devices.
@@ -21,7 +20,6 @@ config VIDEO_ADV_DEBUG
config VIDEO_FIXED_MINOR_RANGES
bool "Enable old-style fixed minor ranges on drivers/video devices"
- default n
help
Say Y here to enable the old-style fixed-range minor assignments.
Only useful if you rely on the old behavior and use mknod instead of udev.
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 89a1fe564675..420e3fc237cd 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -1157,6 +1157,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
case V4L2_CID_FLASH_STROBE_STOP:
case V4L2_CID_AUTO_FOCUS_START:
case V4L2_CID_AUTO_FOCUS_STOP:
+ case V4L2_CID_DO_WHITE_BALANCE:
*type = V4L2_CTRL_TYPE_BUTTON;
*flags |= V4L2_CTRL_FLAG_WRITE_ONLY |
V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index ea1ed88f9dc8..dea8917fd912 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -212,10 +212,10 @@ static int v4l2_fwnode_endpoint_parse_csi2_bus(struct fwnode_handle *fwnode,
have_clk_lane = true;
}
- if (lanes_used & BIT(clock_lane)) {
- if (have_clk_lane || !use_default_lane_mapping)
- pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
- v);
+ if (have_clk_lane && lanes_used & BIT(clock_lane) &&
+ !use_default_lane_mapping) {
+ pr_warn("duplicated lane %u in clock-lanes, using defaults\n",
+ v);
use_default_lane_mapping = true;
}