Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e0694ff authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

Merge branch 'patchwork' into v4l_for_linus

* patchwork:
  [media] s5k4ecgx: select CRC32 helper
  [media] dvb: avoid warning in dvb_net
  [media] v4l: tvp5150: Don't override output pinmuxing at stream on/off time
  [media] v4l: tvp5150: Fix comment regarding output pin muxing
  [media] v4l: tvp5150: Reset device at probe time, not in get/set format handlers
  [media] pctv452e: move buffer to heap, no mutex
  [media] media/cobalt: use pci_irq_allocate_vectors
  [media] cec: fix race between configuring and unconfiguring
  [media] cec: move cec_report_phys_addr into cec_config_thread_func
  [media] cec: replace cec_report_features by cec_fill_msg_report_features
  [media] cec: update log_addr[] before finishing configuration
  [media] cec: CEC_MSG_GIVE_FEATURES should abort for CEC version < 2
  [media] cec: when canceling a message, don't overwrite old status info
  [media] cec: fix report_current_latency
  [media] smiapp: Make suspend and resume functions __maybe_unused
  [media] smiapp: Implement power-on and power-off sequences without runtime PM
parents 65390ea0 c739c0a7
Loading
Loading
Loading
Loading
+52 −51
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@

#include "cec-priv.h"

static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx);
static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx);
static void cec_fill_msg_report_features(struct cec_adapter *adap,
					 struct cec_msg *msg,
					 unsigned int la_idx);

/*
 * 400 ms is the time it takes for one 16 byte message to be
@@ -288,10 +289,10 @@ static void cec_data_cancel(struct cec_data *data)

	/* Mark it as an error */
	data->msg.tx_ts = ktime_get_ns();
	data->msg.tx_status = CEC_TX_STATUS_ERROR |
	data->msg.tx_status |= CEC_TX_STATUS_ERROR |
			       CEC_TX_STATUS_MAX_RETRIES;
	data->msg.tx_error_cnt++;
	data->attempts = 0;
	data->msg.tx_error_cnt = 1;
	/* Queue transmitted message for monitoring purposes */
	cec_queue_msg_monitor(data->adap, &data->msg, 1);

@@ -851,7 +852,7 @@ static const u8 cec_msg_size[256] = {
	[CEC_MSG_REQUEST_ARC_TERMINATION] = 2 | DIRECTED,
	[CEC_MSG_TERMINATE_ARC] = 2 | DIRECTED,
	[CEC_MSG_REQUEST_CURRENT_LATENCY] = 4 | BCAST,
	[CEC_MSG_REPORT_CURRENT_LATENCY] = 7 | BCAST,
	[CEC_MSG_REPORT_CURRENT_LATENCY] = 6 | BCAST,
	[CEC_MSG_CDC_MESSAGE] = 2 | BCAST,
};

@@ -1250,30 +1251,49 @@ static int cec_config_thread_func(void *arg)
		for (i = 1; i < las->num_log_addrs; i++)
			las->log_addr[i] = CEC_LOG_ADDR_INVALID;
	}
	for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
	adap->is_configured = true;
	adap->is_configuring = false;
	cec_post_state_event(adap);
	mutex_unlock(&adap->lock);

	/*
	 * Now post the Report Features and Report Physical Address broadcast
	 * messages. Note that these are non-blocking transmits, meaning that
	 * they are just queued up and once adap->lock is unlocked the main
	 * thread will kick in and start transmitting these.
	 *
	 * If after this function is done (but before one or more of these
	 * messages are actually transmitted) the CEC adapter is unconfigured,
	 * then any remaining messages will be dropped by the main thread.
	 */
	for (i = 0; i < las->num_log_addrs; i++) {
		struct cec_msg msg = {};

		if (las->log_addr[i] == CEC_LOG_ADDR_INVALID ||
		    (las->flags & CEC_LOG_ADDRS_FL_CDC_ONLY))
			continue;

		/*
		 * Report Features must come first according
		 * to CEC 2.0
		 */
		if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED)
			cec_report_features(adap, i);
		cec_report_phys_addr(adap, i);
		msg.msg[0] = (las->log_addr[i] << 4) | 0x0f;

		/* Report Features must come first according to CEC 2.0 */
		if (las->log_addr[i] != CEC_LOG_ADDR_UNREGISTERED &&
		    adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0) {
			cec_fill_msg_report_features(adap, &msg, i);
			cec_transmit_msg_fh(adap, &msg, NULL, false);
		}

		/* Report Physical Address */
		cec_msg_report_physical_addr(&msg, adap->phys_addr,
					     las->primary_device_type[i]);
		dprintk(2, "config: la %d pa %x.%x.%x.%x\n",
			las->log_addr[i],
			cec_phys_addr_exp(adap->phys_addr));
		cec_transmit_msg_fh(adap, &msg, NULL, false);
	}
	for (i = las->num_log_addrs; i < CEC_MAX_LOG_ADDRS; i++)
		las->log_addr[i] = CEC_LOG_ADDR_INVALID;
	mutex_lock(&adap->lock);
	adap->kthread_config = NULL;
	mutex_unlock(&adap->lock);
	complete(&adap->config_completion);
	mutex_unlock(&adap->lock);
	return 0;

unconfigure:
@@ -1526,52 +1546,32 @@ EXPORT_SYMBOL_GPL(cec_s_log_addrs);

/* High-level core CEC message handling */

/* Transmit the Report Features message */
static int cec_report_features(struct cec_adapter *adap, unsigned int la_idx)
/* Fill in the Report Features message */
static void cec_fill_msg_report_features(struct cec_adapter *adap,
					 struct cec_msg *msg,
					 unsigned int la_idx)
{
	struct cec_msg msg = { };
	const struct cec_log_addrs *las = &adap->log_addrs;
	const u8 *features = las->features[la_idx];
	bool op_is_dev_features = false;
	unsigned int idx;

	/* This is 2.0 and up only */
	if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
		return 0;

	/* Report Features */
	msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
	msg.len = 4;
	msg.msg[1] = CEC_MSG_REPORT_FEATURES;
	msg.msg[2] = adap->log_addrs.cec_version;
	msg.msg[3] = las->all_device_types[la_idx];
	msg->msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
	msg->len = 4;
	msg->msg[1] = CEC_MSG_REPORT_FEATURES;
	msg->msg[2] = adap->log_addrs.cec_version;
	msg->msg[3] = las->all_device_types[la_idx];

	/* Write RC Profiles first, then Device Features */
	for (idx = 0; idx < ARRAY_SIZE(las->features[0]); idx++) {
		msg.msg[msg.len++] = features[idx];
		msg->msg[msg->len++] = features[idx];
		if ((features[idx] & CEC_OP_FEAT_EXT) == 0) {
			if (op_is_dev_features)
				break;
			op_is_dev_features = true;
		}
	}
	return cec_transmit_msg(adap, &msg, false);
}

/* Transmit the Report Physical Address message */
static int cec_report_phys_addr(struct cec_adapter *adap, unsigned int la_idx)
{
	const struct cec_log_addrs *las = &adap->log_addrs;
	struct cec_msg msg = { };

	/* Report Physical Address */
	msg.msg[0] = (las->log_addr[la_idx] << 4) | 0x0f;
	cec_msg_report_physical_addr(&msg, adap->phys_addr,
				     las->primary_device_type[la_idx]);
	dprintk(2, "config: la %d pa %x.%x.%x.%x\n",
		las->log_addr[la_idx],
			cec_phys_addr_exp(adap->phys_addr));
	return cec_transmit_msg(adap, &msg, false);
}

/* Transmit the Feature Abort message */
@@ -1777,9 +1777,10 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
	}

	case CEC_MSG_GIVE_FEATURES:
		if (adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0)
			return cec_report_features(adap, la_idx);
		return 0;
		if (adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0)
			return cec_feature_abort(adap, msg);
		cec_fill_msg_report_features(adap, &tx_cec_msg, la_idx);
		return cec_transmit_msg(adap, &tx_cec_msg, false);

	default:
		/*
+5 −10
Original line number Diff line number Diff line
@@ -719,6 +719,9 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
					  ETH_ALEN);
		skb_pull(h->priv->ule_skb, ETH_ALEN);
	} else {
		/* dest_addr buffer is only valid if h->priv->ule_dbit == 0 */
		eth_zero_addr(dest_addr);
	}

	/* Handle ULE Extension Headers. */
@@ -750,16 +753,8 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
	if (!h->priv->ule_bridged) {
		skb_push(h->priv->ule_skb, ETH_HLEN);
		h->ethh = (struct ethhdr *)h->priv->ule_skb->data;
		if (!h->priv->ule_dbit) {
			/*
			 * dest_addr buffer is only valid if
			 * h->priv->ule_dbit == 0
			 */
		memcpy(h->ethh->h_dest, dest_addr, ETH_ALEN);
		eth_zero_addr(h->ethh->h_source);
		} else /* zeroize source and dest */
			memset(h->ethh, 0, ETH_ALEN * 2);

		h->ethh->h_proto = htons(h->priv->ule_sndu_type);
	}
	/* else:  skb is in correct state; nothing to do. */
+1 −0
Original line number Diff line number Diff line
@@ -655,6 +655,7 @@ config VIDEO_S5K6A3
config VIDEO_S5K4ECGX
        tristate "Samsung S5K4ECGX sensor support"
        depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
	select CRC32
        ---help---
          This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
          camera sensor with an embedded SoC image signal processor.
+12 −21
Original line number Diff line number Diff line
@@ -2741,9 +2741,7 @@ static const struct v4l2_subdev_internal_ops smiapp_internal_ops = {
 * I2C Driver
 */

#ifdef CONFIG_PM

static int smiapp_suspend(struct device *dev)
static int __maybe_unused smiapp_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
@@ -2768,7 +2766,7 @@ static int smiapp_suspend(struct device *dev)
	return 0;
}

static int smiapp_resume(struct device *dev)
static int __maybe_unused smiapp_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
@@ -2783,13 +2781,6 @@ static int smiapp_resume(struct device *dev)
	return rval;
}

#else

#define smiapp_suspend	NULL
#define smiapp_resume	NULL

#endif /* CONFIG_PM */

static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev)
{
	struct smiapp_hwconfig *hwcfg;
@@ -2913,13 +2904,9 @@ static int smiapp_probe(struct i2c_client *client,
	if (IS_ERR(sensor->xshutdown))
		return PTR_ERR(sensor->xshutdown);

	pm_runtime_enable(&client->dev);

	rval = pm_runtime_get_sync(&client->dev);
	if (rval < 0) {
		rval = -ENODEV;
		goto out_power_off;
	}
	rval = smiapp_power_on(&client->dev);
	if (rval < 0)
		return rval;

	rval = smiapp_identify_module(sensor);
	if (rval) {
@@ -3100,6 +3087,9 @@ static int smiapp_probe(struct i2c_client *client,
	if (rval < 0)
		goto out_media_entity_cleanup;

	pm_runtime_set_active(&client->dev);
	pm_runtime_get_noresume(&client->dev);
	pm_runtime_enable(&client->dev);
	pm_runtime_set_autosuspend_delay(&client->dev, 1000);
	pm_runtime_use_autosuspend(&client->dev);
	pm_runtime_put_autosuspend(&client->dev);
@@ -3113,8 +3103,7 @@ static int smiapp_probe(struct i2c_client *client,
	smiapp_cleanup(sensor);

out_power_off:
	pm_runtime_put(&client->dev);
	pm_runtime_disable(&client->dev);
	smiapp_power_off(&client->dev);

	return rval;
}
@@ -3127,8 +3116,10 @@ static int smiapp_remove(struct i2c_client *client)

	v4l2_async_unregister_subdev(subdev);

	pm_runtime_suspend(&client->dev);
	pm_runtime_disable(&client->dev);
	if (!pm_runtime_status_suspended(&client->dev))
		smiapp_power_off(&client->dev);
	pm_runtime_set_suspended(&client->dev);

	for (i = 0; i < sensor->ssds_used; i++) {
		v4l2_device_unregister_subdev(&sensor->ssds[i].sd);
+35 −21
Original line number Diff line number Diff line
@@ -291,8 +291,12 @@ static void tvp5150_selmux(struct v4l2_subdev *sd)
	tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode);
	tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input);

	/* Svideo should enable YCrCb output and disable GPCL output
	 * For Composite and TV, it should be the reverse
	/*
	 * Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For
	 * S-Video we output the vertical lock (VLK) signal on FID/GLCO/VLK/HVLK
	 * and set INTREQ/GPCL/VBLK to logic 0. For composite we output the
	 * field indicator (FID) signal on FID/GLCO/VLK/HVLK and set
	 * INTREQ/GPCL/VBLK to logic 1.
	 */
	val = tvp5150_read(sd, TVP5150_MISC_CTL);
	if (val < 0) {
@@ -301,9 +305,9 @@ static void tvp5150_selmux(struct v4l2_subdev *sd)
	}

	if (decoder->input == TVP5150_SVIDEO)
		val = (val & ~0x40) | 0x10;
		val = (val & ~TVP5150_MISC_CTL_GPCL) | TVP5150_MISC_CTL_HVLK;
	else
		val = (val & ~0x10) | 0x40;
		val = (val & ~TVP5150_MISC_CTL_HVLK) | TVP5150_MISC_CTL_GPCL;
	tvp5150_write(sd, TVP5150_MISC_CTL, val);
};

@@ -455,7 +459,12 @@ static const struct i2c_reg_value tvp5150_init_enable[] = {
	},{	/* Automatic offset and AGC enabled */
		TVP5150_ANAL_CHL_CTL, 0x15
	},{	/* Activate YCrCb output 0x9 or 0xd ? */
		TVP5150_MISC_CTL, 0x6f
		TVP5150_MISC_CTL, TVP5150_MISC_CTL_GPCL |
				  TVP5150_MISC_CTL_INTREQ_OE |
				  TVP5150_MISC_CTL_YCBCR_OE |
				  TVP5150_MISC_CTL_SYNC_OE |
				  TVP5150_MISC_CTL_VBLANK |
				  TVP5150_MISC_CTL_CLOCK_OE,
	},{	/* Activates video std autodetection for all standards */
		TVP5150_AUTOSW_MSK, 0x0
	},{	/* Default format: 0x47. For 4:2:2: 0x40 */
@@ -861,8 +870,6 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd,

	f = &format->format;

	tvp5150_reset(sd, 0);

	f->width = decoder->rect.width;
	f->height = decoder->rect.height / 2;

@@ -1051,21 +1058,27 @@ static const struct media_entity_operations tvp5150_sd_media_ops = {
static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct tvp5150 *decoder = to_tvp5150(sd);
	/* Output format: 8-bit ITU-R BT.656 with embedded syncs */
	int val = 0x09;
	int val;

	/* Output format: 8-bit 4:2:2 YUV with discrete sync */
	if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
		val = 0x0d;
	/* Enable or disable the video output signals. */
	val = tvp5150_read(sd, TVP5150_MISC_CTL);
	if (val < 0)
		return val;

	/* Initializes TVP5150 to its default values */
	/* # set PCLK (27MHz) */
	tvp5150_write(sd, TVP5150_CONF_SHARED_PIN, 0x00);
	val &= ~(TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE |
		 TVP5150_MISC_CTL_CLOCK_OE);

	if (enable) {
		/*
		 * Enable the YCbCr and clock outputs. In discrete sync mode
		 * (non-BT.656) additionally enable the the sync outputs.
		 */
		val |= TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_CLOCK_OE;
		if (decoder->mbus_type == V4L2_MBUS_PARALLEL)
			val |= TVP5150_MISC_CTL_SYNC_OE;
	}

	if (enable)
	tvp5150_write(sd, TVP5150_MISC_CTL, val);
	else
		tvp5150_write(sd, TVP5150_MISC_CTL, 0x00);

	return 0;
}
@@ -1524,7 +1537,6 @@ static int tvp5150_probe(struct i2c_client *c,
		res = core->hdl.error;
		goto err;
	}
	v4l2_ctrl_handler_setup(&core->hdl);

	/* Default is no cropping */
	core->rect.top = 0;
@@ -1535,6 +1547,8 @@ static int tvp5150_probe(struct i2c_client *c,
	core->rect.left = 0;
	core->rect.width = TVP5150_H_MAX;

	tvp5150_reset(sd, 0);	/* Calls v4l2_ctrl_handler_setup() */

	res = v4l2_async_register_subdev(sd);
	if (res < 0)
		goto err;
Loading