Merge tag 'media/v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - new dvb frontend driver: lnbh29 - new sensor drivers: imx319 and imx 355 - some old soc_camera driver renames to avoid conflict with new drivers - new i.MX Pixel Pipeline (PXP) mem-to-mem platform driver - a new V4L2 frontend for the FWHT codec - several other improvements, bug fixes, code cleanups, etc * tag 'media/v4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (289 commits) media: rename soc_camera I2C drivers media: cec: forgot to cancel delayed work media: vivid: Support 480p for webcam capture media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD media: vivid: Add 16-bit bayer to format list media: v4l2-tpg-core: Add 16-bit bayer media: pvrusb2: replace `printk` with `pr_*` media: venus: vdec: fix decoded data size media: cx231xx: fix potential sign-extension overflow on large shift media: dt-bindings: media: rcar_vin: add device tree support for r8a7744 media: isif: fix a NULL pointer dereference bug media: exynos4-is: make const array config_ids static media: cx23885: make const array addr_list static media: ivtv: make const array addr_list static media: bttv-input: make const array addr_list static media: cx18: Don't check for address of video_dev media: dw9807-vcm: Fix probe error handling media: dw9714: Remove useless error message media: dw9714: Fix error handling in probe function media: cec: name for RC passthrough device does not need 'RC for' ...
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o
|
||||
cec-objs := cec-core.o cec-adap.o cec-api.o
|
||||
|
||||
ifeq ($(CONFIG_CEC_NOTIFIER),y)
|
||||
cec-objs += cec-notifier.o
|
||||
|
@@ -62,6 +62,19 @@ static unsigned int cec_log_addr2dev(const struct cec_adapter *adap, u8 log_addr
|
||||
return adap->log_addrs.primary_device_type[i < 0 ? 0 : i];
|
||||
}
|
||||
|
||||
u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
|
||||
unsigned int *offset)
|
||||
{
|
||||
unsigned int loc = cec_get_edid_spa_location(edid, size);
|
||||
|
||||
if (offset)
|
||||
*offset = loc;
|
||||
if (loc == 0)
|
||||
return CEC_PHYS_ADDR_INVALID;
|
||||
return (edid[loc] << 8) | edid[loc + 1];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
|
||||
|
||||
/*
|
||||
* Queue a new event for this filehandle. If ts == 0, then set it
|
||||
* to the current time.
|
||||
@@ -341,7 +354,7 @@ static void cec_data_completed(struct cec_data *data)
|
||||
*
|
||||
* This function is called with adap->lock held.
|
||||
*/
|
||||
static void cec_data_cancel(struct cec_data *data)
|
||||
static void cec_data_cancel(struct cec_data *data, u8 tx_status)
|
||||
{
|
||||
/*
|
||||
* It's either the current transmit, or it is a pending
|
||||
@@ -356,13 +369,11 @@ static void cec_data_cancel(struct cec_data *data)
|
||||
}
|
||||
|
||||
if (data->msg.tx_status & CEC_TX_STATUS_OK) {
|
||||
/* Mark the canceled RX as a timeout */
|
||||
data->msg.rx_ts = ktime_get_ns();
|
||||
data->msg.rx_status = CEC_RX_STATUS_TIMEOUT;
|
||||
data->msg.rx_status = CEC_RX_STATUS_ABORTED;
|
||||
} else {
|
||||
/* Mark the canceled TX as an error */
|
||||
data->msg.tx_ts = ktime_get_ns();
|
||||
data->msg.tx_status |= CEC_TX_STATUS_ERROR |
|
||||
data->msg.tx_status |= tx_status |
|
||||
CEC_TX_STATUS_MAX_RETRIES;
|
||||
data->msg.tx_error_cnt++;
|
||||
data->attempts = 0;
|
||||
@@ -390,15 +401,15 @@ static void cec_flush(struct cec_adapter *adap)
|
||||
while (!list_empty(&adap->transmit_queue)) {
|
||||
data = list_first_entry(&adap->transmit_queue,
|
||||
struct cec_data, list);
|
||||
cec_data_cancel(data);
|
||||
cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
||||
}
|
||||
if (adap->transmitting)
|
||||
cec_data_cancel(adap->transmitting);
|
||||
cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED);
|
||||
|
||||
/* Cancel the pending timeout work. */
|
||||
list_for_each_entry_safe(data, n, &adap->wait_queue, list) {
|
||||
if (cancel_delayed_work(&data->work))
|
||||
cec_data_cancel(data);
|
||||
cec_data_cancel(data, CEC_TX_STATUS_OK);
|
||||
/*
|
||||
* If cancel_delayed_work returned false, then
|
||||
* the cec_wait_timeout function is running,
|
||||
@@ -474,12 +485,13 @@ int cec_thread_func(void *_adap)
|
||||
* so much traffic on the bus that the adapter was
|
||||
* unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s).
|
||||
*/
|
||||
dprintk(1, "%s: message %*ph timed out\n", __func__,
|
||||
pr_warn("cec-%s: message %*ph timed out\n", adap->name,
|
||||
adap->transmitting->msg.len,
|
||||
adap->transmitting->msg.msg);
|
||||
adap->tx_timeouts++;
|
||||
/* Just give up on this. */
|
||||
cec_data_cancel(adap->transmitting);
|
||||
cec_data_cancel(adap->transmitting,
|
||||
CEC_TX_STATUS_TIMEOUT);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@@ -514,9 +526,11 @@ int cec_thread_func(void *_adap)
|
||||
if (data->attempts) {
|
||||
/* should be >= 3 data bit periods for a retry */
|
||||
signal_free_time = CEC_SIGNAL_FREE_TIME_RETRY;
|
||||
} else if (data->new_initiator) {
|
||||
} else if (adap->last_initiator !=
|
||||
cec_msg_initiator(&data->msg)) {
|
||||
/* should be >= 5 data bit periods for new initiator */
|
||||
signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
|
||||
adap->last_initiator = cec_msg_initiator(&data->msg);
|
||||
} else {
|
||||
/*
|
||||
* should be >= 7 data bit periods for sending another
|
||||
@@ -530,7 +544,7 @@ int cec_thread_func(void *_adap)
|
||||
/* Tell the adapter to transmit, cancel on error */
|
||||
if (adap->ops->adap_transmit(adap, data->attempts,
|
||||
signal_free_time, &data->msg))
|
||||
cec_data_cancel(data);
|
||||
cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&adap->lock);
|
||||
@@ -701,9 +715,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
||||
struct cec_fh *fh, bool block)
|
||||
{
|
||||
struct cec_data *data;
|
||||
u8 last_initiator = 0xff;
|
||||
unsigned int timeout;
|
||||
int res = 0;
|
||||
|
||||
msg->rx_ts = 0;
|
||||
msg->tx_ts = 0;
|
||||
@@ -813,23 +824,6 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
||||
data->adap = adap;
|
||||
data->blocking = block;
|
||||
|
||||
/*
|
||||
* Determine if this message follows a message from the same
|
||||
* initiator. Needed to determine the free signal time later on.
|
||||
*/
|
||||
if (msg->len > 1) {
|
||||
if (!(list_empty(&adap->transmit_queue))) {
|
||||
const struct cec_data *last;
|
||||
|
||||
last = list_last_entry(&adap->transmit_queue,
|
||||
const struct cec_data, list);
|
||||
last_initiator = cec_msg_initiator(&last->msg);
|
||||
} else if (adap->transmitting) {
|
||||
last_initiator =
|
||||
cec_msg_initiator(&adap->transmitting->msg);
|
||||
}
|
||||
}
|
||||
data->new_initiator = last_initiator != cec_msg_initiator(msg);
|
||||
init_completion(&data->c);
|
||||
INIT_DELAYED_WORK(&data->work, cec_wait_timeout);
|
||||
|
||||
@@ -845,48 +839,23 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg,
|
||||
if (!block)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we don't get a completion before this time something is really
|
||||
* wrong and we time out.
|
||||
*/
|
||||
timeout = CEC_XFER_TIMEOUT_MS;
|
||||
/* Add the requested timeout if we have to wait for a reply as well */
|
||||
if (msg->timeout)
|
||||
timeout += msg->timeout;
|
||||
|
||||
/*
|
||||
* Release the lock and wait, retake the lock afterwards.
|
||||
*/
|
||||
mutex_unlock(&adap->lock);
|
||||
res = wait_for_completion_killable_timeout(&data->c,
|
||||
msecs_to_jiffies(timeout));
|
||||
wait_for_completion_killable(&data->c);
|
||||
if (!data->completed)
|
||||
cancel_delayed_work_sync(&data->work);
|
||||
mutex_lock(&adap->lock);
|
||||
|
||||
if (data->completed) {
|
||||
/* The transmit completed (possibly with an error) */
|
||||
*msg = data->msg;
|
||||
kfree(data);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* The wait for completion timed out or was interrupted, so mark this
|
||||
* as non-blocking and disconnect from the filehandle since it is
|
||||
* still 'in flight'. When it finally completes it will just drop the
|
||||
* result silently.
|
||||
*/
|
||||
data->blocking = false;
|
||||
if (data->fh)
|
||||
list_del(&data->xfer_list);
|
||||
data->fh = NULL;
|
||||
/* Cancel the transmit if it was interrupted */
|
||||
if (!data->completed)
|
||||
cec_data_cancel(data, CEC_TX_STATUS_ABORTED);
|
||||
|
||||
if (res == 0) { /* timed out */
|
||||
/* Check if the reply or the transmit failed */
|
||||
if (msg->timeout && (msg->tx_status & CEC_TX_STATUS_OK))
|
||||
msg->rx_status = CEC_RX_STATUS_TIMEOUT;
|
||||
else
|
||||
msg->tx_status = CEC_TX_STATUS_MAX_RETRIES;
|
||||
}
|
||||
return res > 0 ? 0 : res;
|
||||
/* The transmit completed (possibly with an error) */
|
||||
*msg = data->msg;
|
||||
kfree(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function to be used by drivers and this framework. */
|
||||
@@ -1044,6 +1013,8 @@ void cec_received_msg_ts(struct cec_adapter *adap,
|
||||
mutex_lock(&adap->lock);
|
||||
dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
|
||||
|
||||
adap->last_initiator = 0xff;
|
||||
|
||||
/* Check if this message was for us (directed or broadcast). */
|
||||
if (!cec_msg_is_broadcast(msg))
|
||||
valid_la = cec_has_log_addr(adap, msg_dest);
|
||||
@@ -1506,6 +1477,8 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block)
|
||||
}
|
||||
|
||||
mutex_lock(&adap->devnode.lock);
|
||||
adap->last_initiator = 0xff;
|
||||
|
||||
if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) &&
|
||||
adap->ops->adap_enable(adap, true)) {
|
||||
mutex_unlock(&adap->devnode.lock);
|
||||
|
@@ -77,9 +77,9 @@ static long cec_adap_g_caps(struct cec_adapter *adap,
|
||||
{
|
||||
struct cec_caps caps = {};
|
||||
|
||||
strlcpy(caps.driver, adap->devnode.dev.parent->driver->name,
|
||||
strscpy(caps.driver, adap->devnode.dev.parent->driver->name,
|
||||
sizeof(caps.driver));
|
||||
strlcpy(caps.name, adap->name, sizeof(caps.name));
|
||||
strscpy(caps.name, adap->name, sizeof(caps.name));
|
||||
caps.available_log_addrs = adap->available_log_addrs;
|
||||
caps.capabilities = adap->capabilities;
|
||||
caps.version = LINUX_VERSION_CODE;
|
||||
@@ -101,6 +101,23 @@ static long cec_adap_g_phys_addr(struct cec_adapter *adap,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cec_validate_phys_addr(u16 phys_addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (phys_addr == CEC_PHYS_ADDR_INVALID)
|
||||
return 0;
|
||||
for (i = 0; i < 16; i += 4)
|
||||
if (phys_addr & (0xf << i))
|
||||
break;
|
||||
if (i == 16)
|
||||
return 0;
|
||||
for (i += 4; i < 16; i += 4)
|
||||
if ((phys_addr & (0xf << i)) == 0)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
||||
bool block, __u16 __user *parg)
|
||||
{
|
||||
@@ -112,7 +129,7 @@ static long cec_adap_s_phys_addr(struct cec_adapter *adap, struct cec_fh *fh,
|
||||
if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
|
||||
return -EFAULT;
|
||||
|
||||
err = cec_phys_addr_validate(phys_addr, NULL, NULL);
|
||||
err = cec_validate_phys_addr(phys_addr);
|
||||
if (err)
|
||||
return err;
|
||||
mutex_lock(&adap->lock);
|
||||
@@ -665,6 +682,7 @@ const struct file_operations cec_devnode_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = cec_open,
|
||||
.unlocked_ioctl = cec_ioctl,
|
||||
.compat_ioctl = cec_ioctl,
|
||||
.release = cec_release,
|
||||
.poll = cec_poll,
|
||||
.llseek = no_llseek,
|
||||
|
@@ -264,7 +264,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
|
||||
adap = kzalloc(sizeof(*adap), GFP_KERNEL);
|
||||
if (!adap)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
strlcpy(adap->name, name, sizeof(adap->name));
|
||||
strscpy(adap->name, name, sizeof(adap->name));
|
||||
adap->phys_addr = CEC_PHYS_ADDR_INVALID;
|
||||
adap->cec_pin_is_high = true;
|
||||
adap->log_addrs.cec_version = CEC_OP_CEC_VERSION_2_0;
|
||||
@@ -307,12 +307,10 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
snprintf(adap->device_name, sizeof(adap->device_name),
|
||||
"RC for %s", name);
|
||||
snprintf(adap->input_phys, sizeof(adap->input_phys),
|
||||
"%s/input0", name);
|
||||
"%s/input0", adap->name);
|
||||
|
||||
adap->rc->device_name = adap->device_name;
|
||||
adap->rc->device_name = adap->name;
|
||||
adap->rc->input_phys = adap->input_phys;
|
||||
adap->rc->input_id.bustype = BUS_CEC;
|
||||
adap->rc->input_id.vendor = 0;
|
||||
|
@@ -1,155 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* cec-edid - HDMI Consumer Electronics Control EDID & CEC helper functions
|
||||
*
|
||||
* Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <media/cec.h>
|
||||
|
||||
/*
|
||||
* This EDID is expected to be a CEA-861 compliant, which means that there are
|
||||
* at least two blocks and one or more of the extensions blocks are CEA-861
|
||||
* blocks.
|
||||
*
|
||||
* The returned location is guaranteed to be < size - 1.
|
||||
*/
|
||||
static unsigned int cec_get_edid_spa_location(const u8 *edid, unsigned int size)
|
||||
{
|
||||
unsigned int blocks = size / 128;
|
||||
unsigned int block;
|
||||
u8 d;
|
||||
|
||||
/* Sanity check: at least 2 blocks and a multiple of the block size */
|
||||
if (blocks < 2 || size % 128)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If there are fewer extension blocks than the size, then update
|
||||
* 'blocks'. It is allowed to have more extension blocks than the size,
|
||||
* since some hardware can only read e.g. 256 bytes of the EDID, even
|
||||
* though more blocks are present. The first CEA-861 extension block
|
||||
* should normally be in block 1 anyway.
|
||||
*/
|
||||
if (edid[0x7e] + 1 < blocks)
|
||||
blocks = edid[0x7e] + 1;
|
||||
|
||||
for (block = 1; block < blocks; block++) {
|
||||
unsigned int offset = block * 128;
|
||||
|
||||
/* Skip any non-CEA-861 extension blocks */
|
||||
if (edid[offset] != 0x02 || edid[offset + 1] != 0x03)
|
||||
continue;
|
||||
|
||||
/* search Vendor Specific Data Block (tag 3) */
|
||||
d = edid[offset + 2] & 0x7f;
|
||||
/* Check if there are Data Blocks */
|
||||
if (d <= 4)
|
||||
continue;
|
||||
if (d > 4) {
|
||||
unsigned int i = offset + 4;
|
||||
unsigned int end = offset + d;
|
||||
|
||||
/* Note: 'end' is always < 'size' */
|
||||
do {
|
||||
u8 tag = edid[i] >> 5;
|
||||
u8 len = edid[i] & 0x1f;
|
||||
|
||||
if (tag == 3 && len >= 5 && i + len <= end &&
|
||||
edid[i + 1] == 0x03 &&
|
||||
edid[i + 2] == 0x0c &&
|
||||
edid[i + 3] == 0x00)
|
||||
return i + 4;
|
||||
i += len + 1;
|
||||
} while (i < end);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
|
||||
unsigned int *offset)
|
||||
{
|
||||
unsigned int loc = cec_get_edid_spa_location(edid, size);
|
||||
|
||||
if (offset)
|
||||
*offset = loc;
|
||||
if (loc == 0)
|
||||
return CEC_PHYS_ADDR_INVALID;
|
||||
return (edid[loc] << 8) | edid[loc + 1];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_get_edid_phys_addr);
|
||||
|
||||
void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr)
|
||||
{
|
||||
unsigned int loc = cec_get_edid_spa_location(edid, size);
|
||||
u8 sum = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (loc == 0)
|
||||
return;
|
||||
edid[loc] = phys_addr >> 8;
|
||||
edid[loc + 1] = phys_addr & 0xff;
|
||||
loc &= ~0x7f;
|
||||
|
||||
/* update the checksum */
|
||||
for (i = loc; i < loc + 127; i++)
|
||||
sum += edid[i];
|
||||
edid[i] = 256 - sum;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_set_edid_phys_addr);
|
||||
|
||||
u16 cec_phys_addr_for_input(u16 phys_addr, u8 input)
|
||||
{
|
||||
/* Check if input is sane */
|
||||
if (WARN_ON(input == 0 || input > 0xf))
|
||||
return CEC_PHYS_ADDR_INVALID;
|
||||
|
||||
if (phys_addr == 0)
|
||||
return input << 12;
|
||||
|
||||
if ((phys_addr & 0x0fff) == 0)
|
||||
return phys_addr | (input << 8);
|
||||
|
||||
if ((phys_addr & 0x00ff) == 0)
|
||||
return phys_addr | (input << 4);
|
||||
|
||||
if ((phys_addr & 0x000f) == 0)
|
||||
return phys_addr | input;
|
||||
|
||||
/*
|
||||
* All nibbles are used so no valid physical addresses can be assigned
|
||||
* to the input.
|
||||
*/
|
||||
return CEC_PHYS_ADDR_INVALID;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_phys_addr_for_input);
|
||||
|
||||
int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (parent)
|
||||
*parent = phys_addr;
|
||||
if (port)
|
||||
*port = 0;
|
||||
if (phys_addr == CEC_PHYS_ADDR_INVALID)
|
||||
return 0;
|
||||
for (i = 0; i < 16; i += 4)
|
||||
if (phys_addr & (0xf << i))
|
||||
break;
|
||||
if (i == 16)
|
||||
return 0;
|
||||
if (parent)
|
||||
*parent = phys_addr & (0xfff0 << i);
|
||||
if (port)
|
||||
*port = (phys_addr >> i) & 0xf;
|
||||
for (i += 4; i < 16; i += 4)
|
||||
if ((phys_addr & (0xf << i)) == 0)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cec_phys_addr_validate);
|
@@ -935,6 +935,17 @@ static enum hrtimer_restart cec_pin_timer(struct hrtimer *timer)
|
||||
/* Start bit, switch to receive state */
|
||||
pin->ts = ts;
|
||||
pin->state = CEC_ST_RX_START_BIT_LOW;
|
||||
/*
|
||||
* If a transmit is pending, then that transmit should
|
||||
* use a signal free time of no more than
|
||||
* CEC_SIGNAL_FREE_TIME_NEW_INITIATOR since it will
|
||||
* have a new initiator due to the receive that is now
|
||||
* starting.
|
||||
*/
|
||||
if (pin->tx_msg.len && pin->tx_signal_free_time >
|
||||
CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
|
||||
pin->tx_signal_free_time =
|
||||
CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
|
||||
break;
|
||||
}
|
||||
if (ktime_to_ns(pin->ts) == 0)
|
||||
@@ -1157,6 +1168,15 @@ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts,
|
||||
{
|
||||
struct cec_pin *pin = adap->pin;
|
||||
|
||||
/*
|
||||
* If a receive is in progress, then this transmit should use
|
||||
* a signal free time of max CEC_SIGNAL_FREE_TIME_NEW_INITIATOR
|
||||
* since when it starts transmitting it will have a new initiator.
|
||||
*/
|
||||
if (pin->state != CEC_ST_IDLE &&
|
||||
signal_free_time > CEC_SIGNAL_FREE_TIME_NEW_INITIATOR)
|
||||
signal_free_time = CEC_SIGNAL_FREE_TIME_NEW_INITIATOR;
|
||||
|
||||
pin->tx_signal_free_time = signal_free_time;
|
||||
pin->tx_extra_bytes = 0;
|
||||
pin->tx_msg = *msg;
|
||||
|
@@ -226,12 +226,12 @@ int flexcop_i2c_init(struct flexcop_device *fc)
|
||||
fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
|
||||
fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
|
||||
|
||||
strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
|
||||
sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
|
||||
strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
|
||||
sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
|
||||
strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
|
||||
sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
|
||||
strscpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
|
||||
sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
|
||||
strscpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
|
||||
sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
|
||||
strscpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
|
||||
sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
|
||||
|
||||
i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
|
||||
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
|
||||
|
@@ -569,7 +569,7 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
|
||||
qctrl->step = step;
|
||||
qctrl->default_value = def;
|
||||
qctrl->reserved[0] = qctrl->reserved[1] = 0;
|
||||
strlcpy(qctrl->name, name, sizeof(qctrl->name));
|
||||
strscpy(qctrl->name, name, sizeof(qctrl->name));
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
@@ -606,7 +606,7 @@ int saa7146_register_device(struct video_device *vfd, struct saa7146_dev *dev,
|
||||
vfd->tvnorms = 0;
|
||||
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
|
||||
vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
|
||||
strlcpy(vfd->name, name, sizeof(vfd->name));
|
||||
strscpy(vfd->name, name, sizeof(vfd->name));
|
||||
video_set_drvdata(vfd, dev);
|
||||
|
||||
err = video_register_device(vfd, type, -1);
|
||||
|
@@ -451,8 +451,8 @@ static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
|
||||
strcpy((char *)cap->driver, "saa7146 v4l2");
|
||||
strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
|
||||
strscpy((char *)cap->driver, "saa7146 v4l2", sizeof(cap->driver));
|
||||
strscpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
|
||||
sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
|
||||
cap->device_caps =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
@@ -525,8 +525,8 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
|
||||
{
|
||||
if (f->index >= ARRAY_SIZE(formats))
|
||||
return -EINVAL;
|
||||
strlcpy((char *)f->description, formats[f->index].name,
|
||||
sizeof(f->description));
|
||||
strscpy((char *)f->description, formats[f->index].name,
|
||||
sizeof(f->description));
|
||||
f->pixelformat = formats[f->index].pixelformat;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -450,7 +450,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
|
||||
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (entry) {
|
||||
entry->mode = default_mode;
|
||||
strlcpy(entry->devpath, devpath, sizeof(entry->devpath));
|
||||
strscpy(entry->devpath, devpath, sizeof(entry->devpath));
|
||||
list_add(&entry->entry, &g_smscore_registry);
|
||||
} else
|
||||
pr_err("failed to create smscore_registry.\n");
|
||||
@@ -735,7 +735,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
|
||||
dev->postload_handler = params->postload_handler;
|
||||
|
||||
dev->device_flags = params->flags;
|
||||
strlcpy(dev->devpath, params->devpath, sizeof(dev->devpath));
|
||||
strscpy(dev->devpath, params->devpath, sizeof(dev->devpath));
|
||||
|
||||
smscore_registry_settype(dev->devpath, params->device_type);
|
||||
|
||||
|
@@ -26,10 +26,10 @@ void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
|
||||
const s32 *samples = (const void *)buf;
|
||||
|
||||
for (i = 0; i < len >> 2; i++) {
|
||||
DEFINE_IR_RAW_EVENT(ev);
|
||||
|
||||
ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
|
||||
ev.pulse = (samples[i] > 0) ? false : true;
|
||||
struct ir_raw_event ev = {
|
||||
.duration = abs(samples[i]) * 1000, /* Convert to ns */
|
||||
.pulse = (samples[i] > 0) ? false : true
|
||||
};
|
||||
|
||||
ir_raw_event_store(coredev->ir.dev, &ev);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
|
||||
snprintf(coredev->ir.name, sizeof(coredev->ir.name),
|
||||
"SMS IR (%s)", sms_get_board(board_id)->name);
|
||||
|
||||
strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
|
||||
strscpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
|
||||
strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
|
||||
|
||||
dev->device_name = coredev->ir.name;
|
||||
|
@@ -602,14 +602,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
|
||||
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
|
||||
@@ -658,14 +658,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][5] = { 3138, 657, 810 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][6] = { 731, 680, 3048 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][1] = { 3046, 3054, 886 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][2] = { 0, 3058, 3031 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][3] = { 360, 3079, 877 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][4] = { 3103, 587, 3027 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][5] = { 3116, 723, 861 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][6] = { 789, 744, 3025 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][1] = { 3046, 3054, 886 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][2] = { 0, 3058, 3031 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][3] = { 360, 3079, 877 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][4] = { 3103, 587, 3027 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][5] = { 3116, 723, 861 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][6] = { 789, 744, 3025 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2941, 2950, 546 },
|
||||
[V4L2_COLORSPACE_SMPTE240M][V4L2_XFER_FUNC_SMPTE240M][2] = { 0, 2954, 2924 },
|
||||
@@ -714,14 +714,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
|
||||
[V4L2_COLORSPACE_REC709][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
|
||||
@@ -770,14 +770,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][5] = { 2599, 901, 909 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][6] = { 991, 0, 2966 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SRGB][7] = { 800, 799, 800 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][1] = { 2989, 3120, 1180 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][2] = { 1913, 3011, 3009 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][3] = { 1836, 3099, 1105 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][4] = { 2627, 413, 2966 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][5] = { 2576, 943, 951 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][6] = { 1026, 0, 2942 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][1] = { 2989, 3120, 1180 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][2] = { 1913, 3011, 3009 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][3] = { 1836, 3099, 1105 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][4] = { 2627, 413, 2966 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][5] = { 2576, 943, 951 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][6] = { 1026, 0, 2942 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][1] = { 2879, 3022, 874 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_M][V4L2_XFER_FUNC_SMPTE240M][2] = { 1688, 2903, 2901 },
|
||||
@@ -826,14 +826,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][5] = { 3001, 800, 799 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3071 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 776 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][2] = { 1068, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][3] = { 1068, 3033, 776 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][4] = { 2977, 851, 3048 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][5] = { 2977, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3048 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 776 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][2] = { 1068, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][3] = { 1068, 3033, 776 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][4] = { 2977, 851, 3048 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][5] = { 2977, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3048 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 423 },
|
||||
[V4L2_COLORSPACE_470_SYSTEM_BG][V4L2_XFER_FUNC_SMPTE240M][2] = { 749, 2926, 2926 },
|
||||
@@ -882,14 +882,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][5] = { 3056, 800, 800 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3056 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 851, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 851, 3033, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 3033, 851, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 3033, 851, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][2] = { 851, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][3] = { 851, 3033, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][4] = { 3033, 851, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][5] = { 3033, 851, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 3033 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 507 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 507, 2926, 2926 },
|
||||
@@ -922,62 +922,62 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1812, 886, 886 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1812 },
|
||||
[V4L2_COLORSPACE_SRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][1] = { 3033, 3033, 1063 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][2] = { 1828, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][3] = { 1828, 3033, 1063 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][4] = { 2633, 851, 2979 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][5] = { 2633, 851, 851 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][6] = { 851, 851, 2979 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
|
||||
[V4L2_COLORSPACE_ADOBERGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][1] = { 2939, 2939, 781 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][2] = { 1622, 2939, 2939 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][3] = { 1622, 2939, 781 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][4] = { 2502, 547, 2881 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][5] = { 2502, 547, 547 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][6] = { 547, 547, 2881 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_709][7] = { 547, 547, 547 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][0] = { 3056, 3056, 3056 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][1] = { 3056, 3056, 1031 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][2] = { 1838, 3056, 3056 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][3] = { 1838, 3056, 1031 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][4] = { 2657, 800, 3002 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][5] = { 2657, 800, 800 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][6] = { 800, 800, 3002 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][1] = { 3033, 3033, 1063 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][2] = { 1828, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][3] = { 1828, 3033, 1063 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][4] = { 2633, 851, 2979 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][5] = { 2633, 851, 851 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][6] = { 851, 851, 2979 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][1] = { 2926, 2926, 744 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][2] = { 1594, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][3] = { 1594, 2926, 744 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][4] = { 2484, 507, 2867 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][5] = { 2484, 507, 507 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][6] = { 507, 507, 2867 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE240M][7] = { 507, 507, 507 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][0] = { 2125, 2125, 2125 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][1] = { 2125, 2125, 212 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][2] = { 698, 2125, 2125 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][3] = { 698, 2125, 212 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][4] = { 1557, 130, 2043 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][5] = { 1557, 130, 130 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][6] = { 130, 130, 2043 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_NONE][7] = { 130, 130, 130 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][0] = { 3175, 3175, 3175 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][1] = { 3175, 3175, 1308 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][2] = { 2069, 3175, 3175 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][3] = { 2069, 3175, 1308 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][4] = { 2816, 1084, 3127 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][5] = { 2816, 1084, 1084 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][6] = { 1084, 1084, 3127 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_DCI_P3][7] = { 1084, 1084, 1084 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][0] = { 1812, 1812, 1812 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][1] = { 1812, 1812, 1022 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][2] = { 1402, 1812, 1812 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][3] = { 1402, 1812, 1022 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][4] = { 1692, 886, 1797 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][5] = { 1692, 886, 886 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][6] = { 886, 886, 1797 },
|
||||
[V4L2_COLORSPACE_OPRGB][V4L2_XFER_FUNC_SMPTE2084][7] = { 886, 886, 886 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][1] = { 2877, 2923, 1058 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_709][2] = { 1837, 2840, 2916 },
|
||||
@@ -994,14 +994,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][5] = { 2517, 1159, 900 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][6] = { 1042, 870, 2917 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 800 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][1] = { 2976, 3018, 1315 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][2] = { 2024, 2942, 3011 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][3] = { 1930, 2926, 1256 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][4] = { 2563, 1227, 2916 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][5] = { 2494, 1183, 943 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][6] = { 1073, 916, 2894 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][1] = { 2976, 3018, 1315 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][2] = { 2024, 2942, 3011 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][3] = { 1930, 2926, 1256 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][4] = { 2563, 1227, 2916 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][5] = { 2494, 1183, 943 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][6] = { 1073, 916, 2894 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][1] = { 2864, 2910, 1024 },
|
||||
[V4L2_COLORSPACE_BT2020][V4L2_XFER_FUNC_SMPTE240M][2] = { 1811, 2826, 2903 },
|
||||
@@ -1050,14 +1050,14 @@ const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFE
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][5] = { 2880, 998, 902 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][6] = { 816, 823, 2940 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SRGB][7] = { 800, 800, 799 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][1] = { 3029, 3028, 1255 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][2] = { 1406, 2988, 3011 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][3] = { 1398, 2983, 1190 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][4] = { 2860, 1050, 2939 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][5] = { 2857, 1033, 945 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][6] = { 866, 873, 2916 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_ADOBERGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][0] = { 3033, 3033, 3033 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][1] = { 3029, 3028, 1255 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][2] = { 1406, 2988, 3011 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][3] = { 1398, 2983, 1190 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][4] = { 2860, 1050, 2939 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][5] = { 2857, 1033, 945 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][6] = { 866, 873, 2916 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_OPRGB][7] = { 851, 851, 851 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][0] = { 2926, 2926, 2926 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][1] = { 2923, 2921, 957 },
|
||||
[V4L2_COLORSPACE_DCI_P3][V4L2_XFER_FUNC_SMPTE240M][2] = { 1125, 2877, 2902 },
|
||||
@@ -1128,7 +1128,7 @@ static const double rec709_to_240m[3][3] = {
|
||||
{ 0.0016327, 0.0044133, 0.9939540 },
|
||||
};
|
||||
|
||||
static const double rec709_to_adobergb[3][3] = {
|
||||
static const double rec709_to_oprgb[3][3] = {
|
||||
{ 0.7151627, 0.2848373, -0.0000000 },
|
||||
{ 0.0000000, 1.0000000, 0.0000000 },
|
||||
{ -0.0000000, 0.0411705, 0.9588295 },
|
||||
@@ -1195,7 +1195,7 @@ static double transfer_rec709_to_rgb(double v)
|
||||
return (v < 0.081) ? v / 4.5 : pow((v + 0.099) / 1.099, 1.0 / 0.45);
|
||||
}
|
||||
|
||||
static double transfer_rgb_to_adobergb(double v)
|
||||
static double transfer_rgb_to_oprgb(double v)
|
||||
{
|
||||
return pow(v, 1.0 / 2.19921875);
|
||||
}
|
||||
@@ -1251,8 +1251,8 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
|
||||
case V4L2_COLORSPACE_470_SYSTEM_M:
|
||||
mult_matrix(r, g, b, rec709_to_ntsc1953);
|
||||
break;
|
||||
case V4L2_COLORSPACE_ADOBERGB:
|
||||
mult_matrix(r, g, b, rec709_to_adobergb);
|
||||
case V4L2_COLORSPACE_OPRGB:
|
||||
mult_matrix(r, g, b, rec709_to_oprgb);
|
||||
break;
|
||||
case V4L2_COLORSPACE_BT2020:
|
||||
mult_matrix(r, g, b, rec709_to_bt2020);
|
||||
@@ -1284,10 +1284,10 @@ static void csc(enum v4l2_colorspace colorspace, enum v4l2_xfer_func xfer_func,
|
||||
*g = transfer_rgb_to_srgb(*g);
|
||||
*b = transfer_rgb_to_srgb(*b);
|
||||
break;
|
||||
case V4L2_XFER_FUNC_ADOBERGB:
|
||||
*r = transfer_rgb_to_adobergb(*r);
|
||||
*g = transfer_rgb_to_adobergb(*g);
|
||||
*b = transfer_rgb_to_adobergb(*b);
|
||||
case V4L2_XFER_FUNC_OPRGB:
|
||||
*r = transfer_rgb_to_oprgb(*r);
|
||||
*g = transfer_rgb_to_oprgb(*g);
|
||||
*b = transfer_rgb_to_oprgb(*b);
|
||||
break;
|
||||
case V4L2_XFER_FUNC_DCI_P3:
|
||||
*r = transfer_rgb_to_dcip3(*r);
|
||||
@@ -1321,7 +1321,7 @@ int main(int argc, char **argv)
|
||||
V4L2_COLORSPACE_470_SYSTEM_BG,
|
||||
0,
|
||||
V4L2_COLORSPACE_SRGB,
|
||||
V4L2_COLORSPACE_ADOBERGB,
|
||||
V4L2_COLORSPACE_OPRGB,
|
||||
V4L2_COLORSPACE_BT2020,
|
||||
0,
|
||||
V4L2_COLORSPACE_DCI_P3,
|
||||
@@ -1336,7 +1336,7 @@ int main(int argc, char **argv)
|
||||
"V4L2_COLORSPACE_470_SYSTEM_BG",
|
||||
"",
|
||||
"V4L2_COLORSPACE_SRGB",
|
||||
"V4L2_COLORSPACE_ADOBERGB",
|
||||
"V4L2_COLORSPACE_OPRGB",
|
||||
"V4L2_COLORSPACE_BT2020",
|
||||
"",
|
||||
"V4L2_COLORSPACE_DCI_P3",
|
||||
@@ -1345,7 +1345,7 @@ int main(int argc, char **argv)
|
||||
"",
|
||||
"V4L2_XFER_FUNC_709",
|
||||
"V4L2_XFER_FUNC_SRGB",
|
||||
"V4L2_XFER_FUNC_ADOBERGB",
|
||||
"V4L2_XFER_FUNC_OPRGB",
|
||||
"V4L2_XFER_FUNC_SMPTE240M",
|
||||
"V4L2_XFER_FUNC_NONE",
|
||||
"V4L2_XFER_FUNC_DCI_P3",
|
||||
|
@@ -202,6 +202,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SRGGB12:
|
||||
case V4L2_PIX_FMT_SBGGR16:
|
||||
case V4L2_PIX_FMT_SGBRG16:
|
||||
case V4L2_PIX_FMT_SGRBG16:
|
||||
case V4L2_PIX_FMT_SRGGB16:
|
||||
tpg->interleaved = true;
|
||||
tpg->vdownsampling[1] = 1;
|
||||
tpg->hdownsampling[1] = 1;
|
||||
@@ -235,6 +239,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y16:
|
||||
case V4L2_PIX_FMT_Y16_BE:
|
||||
case V4L2_PIX_FMT_Z16:
|
||||
tpg->color_enc = TGP_COLOR_ENC_LUMA;
|
||||
break;
|
||||
case V4L2_PIX_FMT_YUV444:
|
||||
@@ -351,6 +356,7 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
|
||||
case V4L2_PIX_FMT_Y12:
|
||||
case V4L2_PIX_FMT_Y16:
|
||||
case V4L2_PIX_FMT_Y16_BE:
|
||||
case V4L2_PIX_FMT_Z16:
|
||||
tpg->twopixelsize[0] = 2 * 2;
|
||||
break;
|
||||
case V4L2_PIX_FMT_RGB24:
|
||||
@@ -392,6 +398,10 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SBGGR12:
|
||||
case V4L2_PIX_FMT_SRGGB16:
|
||||
case V4L2_PIX_FMT_SGRBG16:
|
||||
case V4L2_PIX_FMT_SGBRG16:
|
||||
case V4L2_PIX_FMT_SBGGR16:
|
||||
tpg->twopixelsize[0] = 4;
|
||||
tpg->twopixelsize[1] = 4;
|
||||
break;
|
||||
@@ -1062,6 +1072,7 @@ static void gen_twopix(struct tpg_data *tpg,
|
||||
buf[0][offset+1] = r_y_h >> 4;
|
||||
break;
|
||||
case V4L2_PIX_FMT_Y16:
|
||||
case V4L2_PIX_FMT_Z16:
|
||||
/*
|
||||
* Ideally both bytes should be set to r_y_h, but then you won't
|
||||
* be able to detect endian problems. So keep it 0 except for
|
||||
@@ -1355,6 +1366,22 @@ static void gen_twopix(struct tpg_data *tpg,
|
||||
buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
|
||||
buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SBGGR16:
|
||||
buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : b_v;
|
||||
buf[1][offset] = buf[1][offset + 1] = odd ? r_y_h : g_u_s;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SGBRG16:
|
||||
buf[0][offset] = buf[0][offset + 1] = odd ? b_v : g_u_s;
|
||||
buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : r_y_h;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SGRBG16:
|
||||
buf[0][offset] = buf[0][offset + 1] = odd ? r_y_h : g_u_s;
|
||||
buf[1][offset] = buf[1][offset + 1] = odd ? g_u_s : b_v;
|
||||
break;
|
||||
case V4L2_PIX_FMT_SRGGB16:
|
||||
buf[0][offset] = buf[0][offset + 1] = odd ? g_u_s : r_y_h;
|
||||
buf[1][offset] = buf[1][offset + 1] = odd ? b_v : g_u_s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,6 +1400,10 @@ unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
|
||||
case V4L2_PIX_FMT_SGBRG12:
|
||||
case V4L2_PIX_FMT_SGRBG12:
|
||||
case V4L2_PIX_FMT_SRGGB12:
|
||||
case V4L2_PIX_FMT_SBGGR16:
|
||||
case V4L2_PIX_FMT_SGBRG16:
|
||||
case V4L2_PIX_FMT_SGRBG16:
|
||||
case V4L2_PIX_FMT_SRGGB16:
|
||||
return buf_line & 1;
|
||||
default:
|
||||
return 0;
|
||||
@@ -1770,7 +1801,7 @@ typedef struct { u16 __; u8 _; } __packed x24;
|
||||
pos[7] = (chr & (0x01 << 0) ? fg : bg); \
|
||||
} \
|
||||
\
|
||||
pos += (tpg->hflip ? -8 : 8) / hdiv; \
|
||||
pos += (tpg->hflip ? -8 : 8) / (int)hdiv; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -2038,8 +2069,12 @@ void tpg_log_status(struct tpg_data *tpg)
|
||||
tpg->compose.left, tpg->compose.top);
|
||||
pr_info("tpg colorspace: %d\n", tpg->colorspace);
|
||||
pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
|
||||
pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
|
||||
pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc);
|
||||
if (tpg->color_enc == TGP_COLOR_ENC_HSV)
|
||||
pr_info("tpg HSV encoding: %d/%d\n",
|
||||
tpg->hsv_enc, tpg->real_hsv_enc);
|
||||
else if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
|
||||
pr_info("tpg Y'CbCr encoding: %d/%d\n",
|
||||
tpg->ycbcr_enc, tpg->real_ycbcr_enc);
|
||||
pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
|
||||
pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
|
||||
}
|
||||
|
@@ -661,6 +661,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
|
||||
{
|
||||
unsigned int num_buffers, allocated_buffers, num_planes = 0;
|
||||
unsigned plane_sizes[VB2_MAX_PLANES] = { };
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (q->streaming) {
|
||||
@@ -718,6 +719,14 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Check that driver has set sane values */
|
||||
if (WARN_ON(!num_planes))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num_planes; i++)
|
||||
if (WARN_ON(!plane_sizes[i]))
|
||||
return -EINVAL;
|
||||
|
||||
/* Finally, allocate buffers and video memory */
|
||||
allocated_buffers =
|
||||
__vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
|
||||
|
@@ -1265,6 +1265,7 @@ static const struct file_operations dvb_demux_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = dvb_demux_read,
|
||||
.unlocked_ioctl = dvb_demux_ioctl,
|
||||
.compat_ioctl = dvb_demux_ioctl,
|
||||
.open = dvb_demux_open,
|
||||
.release = dvb_demux_release,
|
||||
.poll = dvb_demux_poll,
|
||||
|
@@ -2422,7 +2422,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
||||
struct dvb_frontend_info *info = parg;
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
strcpy(info->name, fe->ops.info.name);
|
||||
strscpy(info->name, fe->ops.info.name, sizeof(info->name));
|
||||
info->symbol_rate_min = fe->ops.info.symbol_rate_min;
|
||||
info->symbol_rate_max = fe->ops.info.symbol_rate_max;
|
||||
info->symbol_rate_tolerance = fe->ops.info.symbol_rate_tolerance;
|
||||
|
@@ -194,7 +194,7 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
|
||||
spin_lock_init(&ctx->slock);
|
||||
INIT_LIST_HEAD(&ctx->dvb_q);
|
||||
|
||||
strlcpy(ctx->name, name, DVB_VB2_NAME_MAX);
|
||||
strscpy(ctx->name, name, DVB_VB2_NAME_MAX);
|
||||
ctx->nonblocking = nonblocking;
|
||||
ctx->state = DVB_VB2_STATE_INIT;
|
||||
|
||||
|
@@ -621,7 +621,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||
unsigned demux_pad = 0;
|
||||
unsigned dvr_pad = 0;
|
||||
unsigned ntuner = 0, ndemod = 0;
|
||||
int ret;
|
||||
int ret, pad_source, pad_sink;
|
||||
static const char *connector_name = "Television";
|
||||
|
||||
if (!mdev)
|
||||
@@ -681,7 +681,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ntuner)
|
||||
if (!ntuner) {
|
||||
ret = media_create_pad_links(mdev,
|
||||
MEDIA_ENT_F_CONN_RF,
|
||||
conn, 0,
|
||||
@@ -689,22 +689,31 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
||||
demod, 0,
|
||||
MEDIA_LNK_FL_ENABLED,
|
||||
false);
|
||||
else
|
||||
} else {
|
||||
pad_sink = media_get_pad_index(tuner, true,
|
||||
PAD_SIGNAL_ANALOG);
|
||||
if (pad_sink < 0)
|
||||
return -EINVAL;
|
||||
ret = media_create_pad_links(mdev,
|
||||
MEDIA_ENT_F_CONN_RF,
|
||||
conn, 0,
|
||||
MEDIA_ENT_F_TUNER,
|
||||
tuner, TUNER_PAD_RF_INPUT,
|
||||
tuner, pad_sink,
|
||||
MEDIA_LNK_FL_ENABLED,
|
||||
false);
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ntuner && ndemod) {
|
||||
pad_source = media_get_pad_index(tuner, true,
|
||||
PAD_SIGNAL_ANALOG);
|
||||
if (pad_source)
|
||||
return -EINVAL;
|
||||
ret = media_create_pad_links(mdev,
|
||||
MEDIA_ENT_F_TUNER,
|
||||
tuner, TUNER_PAD_OUTPUT,
|
||||
tuner, pad_source,
|
||||
MEDIA_ENT_F_DTV_DEMOD,
|
||||
demod, 0, MEDIA_LNK_FL_ENABLED,
|
||||
false);
|
||||
@@ -967,9 +976,9 @@ struct i2c_client *dvb_module_probe(const char *module_name,
|
||||
return NULL;
|
||||
|
||||
if (name)
|
||||
strlcpy(board_info->type, name, I2C_NAME_SIZE);
|
||||
strscpy(board_info->type, name, I2C_NAME_SIZE);
|
||||
else
|
||||
strlcpy(board_info->type, module_name, I2C_NAME_SIZE);
|
||||
strscpy(board_info->type, module_name, I2C_NAME_SIZE);
|
||||
|
||||
board_info->addr = addr;
|
||||
board_info->platform_data = platform_data;
|
||||
|
@@ -791,6 +791,16 @@ config DVB_LNBH25
|
||||
An SEC control chip.
|
||||
Say Y when you want to support this chip.
|
||||
|
||||
config DVB_LNBH29
|
||||
tristate "LNBH29 SEC controller"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
LNB power supply and control voltage
|
||||
regulator chip with step-up converter
|
||||
and I2C interface for STMicroelectronics LNBH29.
|
||||
Say Y when you want to support this chip.
|
||||
|
||||
config DVB_LNBP21
|
||||
tristate "LNBP21/LNBH24 SEC controllers"
|
||||
depends on DVB_CORE && I2C
|
||||
|
@@ -58,6 +58,7 @@ obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
|
||||
obj-$(CONFIG_DVB_LG2160) += lg2160.o
|
||||
obj-$(CONFIG_DVB_CX24123) += cx24123.o
|
||||
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
|
||||
obj-$(CONFIG_DVB_LNBH29) += lnbh29.o
|
||||
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
|
||||
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
|
||||
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
|
||||
|
@@ -718,10 +718,12 @@ static int au8522_probe(struct i2c_client *client,
|
||||
v4l2_i2c_subdev_init(sd, client, &au8522_ops);
|
||||
#if defined(CONFIG_MEDIA_CONTROLLER)
|
||||
|
||||
state->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
|
||||
state->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[DEMOD_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[AU8522_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
|
||||
state->pads[AU8522_PAD_IF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
|
||||
state->pads[AU8522_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[AU8522_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;
|
||||
state->pads[AU8522_PAD_AUDIO_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[AU8522_PAD_AUDIO_OUT].sig_type = PAD_SIGNAL_AUDIO;
|
||||
sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
|
||||
|
||||
ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),
|
||||
|
@@ -40,6 +40,13 @@
|
||||
#define AU8522_DIGITAL_MODE 1
|
||||
#define AU8522_SUSPEND_MODE 2
|
||||
|
||||
enum au8522_pads {
|
||||
AU8522_PAD_IF_INPUT,
|
||||
AU8522_PAD_VID_OUT,
|
||||
AU8522_PAD_AUDIO_OUT,
|
||||
AU8522_NUM_PADS
|
||||
};
|
||||
|
||||
struct au8522_state {
|
||||
struct i2c_client *c;
|
||||
struct i2c_adapter *i2c;
|
||||
@@ -71,7 +78,7 @@ struct au8522_state {
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
|
||||
#ifdef CONFIG_MEDIA_CONTROLLER
|
||||
struct media_pad pads[DEMOD_NUM_PADS];
|
||||
struct media_pad pads[AU8522_NUM_PADS];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -1087,7 +1087,7 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
|
||||
if (config->dont_use_pll)
|
||||
cx24123_repeater_mode(state, 1, 0);
|
||||
|
||||
strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
|
||||
strscpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
|
||||
sizeof(state->tuner_i2c_adapter.name));
|
||||
state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
|
||||
state->tuner_i2c_adapter.algo_data = NULL;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* cxd2099.c: Driver for the Sony CXD2099AR Common Interface Controller
|
||||
*
|
||||
@@ -701,4 +702,4 @@ module_i2c_driver(cxd2099_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Sony CXD2099AR Common Interface controller driver");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* cxd2099.h: Driver for the Sony CXD2099AR Common Interface Controller
|
||||
*
|
||||
|
@@ -540,7 +540,7 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config,
|
||||
pdata.attach_in_use = true;
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
|
||||
strscpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);
|
||||
board_info.addr = config->i2c_address;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(adapter, &board_info);
|
||||
|
@@ -424,7 +424,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
|
||||
struct i2c_algorithm *algo, const char *name,
|
||||
struct dibx000_i2c_master *mst)
|
||||
{
|
||||
strlcpy(i2c_adap->name, name, sizeof(i2c_adap->name));
|
||||
strscpy(i2c_adap->name, name, sizeof(i2c_adap->name));
|
||||
i2c_adap->algo = algo;
|
||||
i2c_adap->algo_data = NULL;
|
||||
i2c_set_adapdata(i2c_adap, mst);
|
||||
|
@@ -3555,8 +3555,8 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
|
||||
if (!ext_attr->has_smatx)
|
||||
return -EIO;
|
||||
switch (uio_cfg->mode) {
|
||||
case DRX_UIO_MODE_FIRMWARE_SMA: /* falltrough */
|
||||
case DRX_UIO_MODE_FIRMWARE_SAW: /* falltrough */
|
||||
case DRX_UIO_MODE_FIRMWARE_SMA: /* fall through */
|
||||
case DRX_UIO_MODE_FIRMWARE_SAW: /* fall through */
|
||||
case DRX_UIO_MODE_READWRITE:
|
||||
ext_attr->uio_sma_tx_mode = uio_cfg->mode;
|
||||
break;
|
||||
@@ -3579,7 +3579,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
|
||||
if (!ext_attr->has_smarx)
|
||||
return -EIO;
|
||||
switch (uio_cfg->mode) {
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* fall through */
|
||||
case DRX_UIO_MODE_READWRITE:
|
||||
ext_attr->uio_sma_rx_mode = uio_cfg->mode;
|
||||
break;
|
||||
@@ -3603,7 +3603,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
|
||||
if (!ext_attr->has_gpio)
|
||||
return -EIO;
|
||||
switch (uio_cfg->mode) {
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* fall through */
|
||||
case DRX_UIO_MODE_READWRITE:
|
||||
ext_attr->uio_gpio_mode = uio_cfg->mode;
|
||||
break;
|
||||
@@ -3639,7 +3639,7 @@ static int ctrl_set_uio_cfg(struct drx_demod_instance *demod, struct drxuio_cfg
|
||||
}
|
||||
ext_attr->uio_irqn_mode = uio_cfg->mode;
|
||||
break;
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* falltrough */
|
||||
case DRX_UIO_MODE_FIRMWARE0: /* fall through */
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
@@ -929,7 +929,7 @@ struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
|
||||
struct i2c_board_info board_info = {};
|
||||
struct lgdt330x_config config = *_config;
|
||||
|
||||
strlcpy(board_info.type, "lgdt330x", sizeof(board_info.type));
|
||||
strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
|
||||
board_info.addr = demod_address;
|
||||
board_info.platform_data = &config;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
|
168
drivers/media/dvb-frontends/lnbh29.c
Normal file
168
drivers/media/dvb-frontends/lnbh29.c
Normal file
@@ -0,0 +1,168 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// Driver for LNB supply and control IC STMicroelectronics LNBH29
|
||||
//
|
||||
// Copyright (c) 2018 Socionext Inc.
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <media/dvb_frontend.h>
|
||||
#include "lnbh29.h"
|
||||
|
||||
/**
|
||||
* struct lnbh29_priv - LNBH29 driver private data
|
||||
* @i2c: Pointer to the I2C adapter structure
|
||||
* @i2c_address: I2C address of LNBH29 chip
|
||||
* @config: Registers configuration
|
||||
* offset 0: 1st register address, always 0x01 (DATA)
|
||||
* offset 1: DATA register value
|
||||
*/
|
||||
struct lnbh29_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
u8 i2c_address;
|
||||
u8 config[2];
|
||||
};
|
||||
|
||||
#define LNBH29_STATUS_OLF BIT(0)
|
||||
#define LNBH29_STATUS_OTF BIT(1)
|
||||
#define LNBH29_STATUS_VMON BIT(2)
|
||||
#define LNBH29_STATUS_PNG BIT(3)
|
||||
#define LNBH29_STATUS_PDO BIT(4)
|
||||
#define LNBH29_VSEL_MASK GENMASK(2, 0)
|
||||
#define LNBH29_VSEL_0 0x00
|
||||
/* Min: 13.188V, Typ: 13.667V, Max:14V */
|
||||
#define LNBH29_VSEL_13 0x03
|
||||
/* Min: 18.158V, Typ: 18.817V, Max:19.475V */
|
||||
#define LNBH29_VSEL_18 0x07
|
||||
|
||||
static int lnbh29_read_vmon(struct lnbh29_priv *priv)
|
||||
{
|
||||
u8 addr = 0x00;
|
||||
u8 status[2];
|
||||
int ret;
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = priv->i2c_address,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = &addr
|
||||
}, {
|
||||
.addr = priv->i2c_address,
|
||||
.flags = I2C_M_RD,
|
||||
.len = sizeof(status),
|
||||
.buf = status
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 2);
|
||||
if (ret >= 0 && ret != 2)
|
||||
ret = -EIO;
|
||||
if (ret < 0) {
|
||||
dev_dbg(&priv->i2c->dev, "LNBH29 I2C transfer failed (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (status[0] & (LNBH29_STATUS_OLF | LNBH29_STATUS_VMON)) {
|
||||
dev_err(&priv->i2c->dev,
|
||||
"LNBH29 voltage in failure state, status reg 0x%x\n",
|
||||
status[0]);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnbh29_set_voltage(struct dvb_frontend *fe,
|
||||
enum fe_sec_voltage voltage)
|
||||
{
|
||||
struct lnbh29_priv *priv = fe->sec_priv;
|
||||
u8 data_reg;
|
||||
int ret;
|
||||
struct i2c_msg msg = {
|
||||
.addr = priv->i2c_address,
|
||||
.flags = 0,
|
||||
.len = sizeof(priv->config),
|
||||
.buf = priv->config
|
||||
};
|
||||
|
||||
switch (voltage) {
|
||||
case SEC_VOLTAGE_OFF:
|
||||
data_reg = LNBH29_VSEL_0;
|
||||
break;
|
||||
case SEC_VOLTAGE_13:
|
||||
data_reg = LNBH29_VSEL_13;
|
||||
break;
|
||||
case SEC_VOLTAGE_18:
|
||||
data_reg = LNBH29_VSEL_18;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->config[1] &= ~LNBH29_VSEL_MASK;
|
||||
priv->config[1] |= data_reg;
|
||||
|
||||
ret = i2c_transfer(priv->i2c, &msg, 1);
|
||||
if (ret >= 0 && ret != 1)
|
||||
ret = -EIO;
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->i2c->dev, "LNBH29 I2C transfer error (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Soft-start time (Vout 0V to 18V) is Typ. 6ms. */
|
||||
usleep_range(6000, 20000);
|
||||
|
||||
if (voltage == SEC_VOLTAGE_OFF)
|
||||
return 0;
|
||||
|
||||
return lnbh29_read_vmon(priv);
|
||||
}
|
||||
|
||||
static void lnbh29_release(struct dvb_frontend *fe)
|
||||
{
|
||||
lnbh29_set_voltage(fe, SEC_VOLTAGE_OFF);
|
||||
kfree(fe->sec_priv);
|
||||
fe->sec_priv = NULL;
|
||||
}
|
||||
|
||||
struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
|
||||
struct lnbh29_config *cfg,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct lnbh29_priv *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return NULL;
|
||||
|
||||
priv->i2c_address = (cfg->i2c_address >> 1);
|
||||
priv->i2c = i2c;
|
||||
priv->config[0] = 0x01;
|
||||
priv->config[1] = cfg->data_config;
|
||||
fe->sec_priv = priv;
|
||||
|
||||
if (lnbh29_set_voltage(fe, SEC_VOLTAGE_OFF)) {
|
||||
dev_err(&i2c->dev, "no LNBH29 found at I2C addr 0x%02x\n",
|
||||
priv->i2c_address);
|
||||
kfree(priv);
|
||||
fe->sec_priv = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fe->ops.release_sec = lnbh29_release;
|
||||
fe->ops.set_voltage = lnbh29_set_voltage;
|
||||
|
||||
dev_info(&i2c->dev, "LNBH29 attached at I2C addr 0x%02x\n",
|
||||
priv->i2c_address);
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(lnbh29_attach);
|
||||
|
||||
MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
|
||||
MODULE_DESCRIPTION("STMicroelectronics LNBH29 driver");
|
||||
MODULE_LICENSE("GPL v2");
|
36
drivers/media/dvb-frontends/lnbh29.h
Normal file
36
drivers/media/dvb-frontends/lnbh29.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for LNB supply and control IC STMicroelectronics LNBH29
|
||||
*
|
||||
* Copyright (c) 2018 Socionext Inc.
|
||||
*/
|
||||
|
||||
#ifndef LNBH29_H
|
||||
#define LNBH29_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
/* Using very low E.S.R. capacitors or ceramic caps */
|
||||
#define LNBH29_DATA_COMP BIT(3)
|
||||
|
||||
struct lnbh29_config {
|
||||
u8 i2c_address;
|
||||
u8 data_config;
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_DVB_LNBH29)
|
||||
struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
|
||||
struct lnbh29_config *cfg,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe,
|
||||
struct lnbh29_config *cfg,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1284,7 +1284,7 @@ struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg,
|
||||
pdata.attach_in_use = true;
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
|
||||
strscpy(board_info.type, "m88ds3103", I2C_NAME_SIZE);
|
||||
board_info.addr = cfg->i2c_addr;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
|
@@ -815,17 +815,20 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config,
|
||||
|
||||
switch (state->id) {
|
||||
case ID_VP310:
|
||||
strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
|
||||
strscpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
state->xtal = MT312_PLL_CLK;
|
||||
state->freq_mult = 9;
|
||||
break;
|
||||
case ID_MT312:
|
||||
strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
|
||||
strscpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
state->xtal = MT312_PLL_CLK;
|
||||
state->freq_mult = 6;
|
||||
break;
|
||||
case ID_ZL10313:
|
||||
strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
|
||||
strscpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
state->xtal = MT312_PLL_CLK_10_111;
|
||||
state->freq_mult = 9;
|
||||
break;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for the MaxLinear MxL5xx family of tuners/demods
|
||||
*
|
||||
@@ -17,7 +18,6 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -739,6 +739,7 @@ static int get_frontend(struct dvb_frontend *fe,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
case SYS_DVBS:
|
||||
switch ((enum MXL_HYDRA_MODULATION_E)
|
||||
reg_data[DMD_MODULATION_SCHEME_ADDR]) {
|
||||
@@ -1893,4 +1894,4 @@ EXPORT_SYMBOL_GPL(mxl5xx_attach);
|
||||
|
||||
MODULE_DESCRIPTION("MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -1,3 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for the MaxLinear MxL5xx family of tuners/demods
|
||||
*
|
||||
* Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* developed for Digital Devices GmbH
|
||||
*
|
||||
* based on code:
|
||||
* Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
|
||||
* which was released under GPL V2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _MXL5XX_H_
|
||||
#define _MXL5XX_H_
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Defines for the Maxlinear MX58x family of tuners/demods
|
||||
*
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
|
||||
*
|
||||
|
@@ -439,8 +439,8 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
|
||||
|
||||
dev_dbg(&pdev->dev, "\n");
|
||||
|
||||
strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
|
||||
strlcpy(cap->card, dev->vdev.name, sizeof(cap->card));
|
||||
strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
|
||||
strscpy(cap->card, dev->vdev.name, sizeof(cap->card));
|
||||
usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
|
||||
cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_READWRITE | V4L2_CAP_TUNER;
|
||||
@@ -976,7 +976,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
|
||||
dev_dbg(&pdev->dev, "index=%d type=%d\n", v->index, v->type);
|
||||
|
||||
if (v->index == 0) {
|
||||
strlcpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
|
||||
strscpy(v->name, "ADC: Realtek RTL2832", sizeof(v->name));
|
||||
v->type = V4L2_TUNER_ADC;
|
||||
v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
|
||||
v->rangelow = 300000;
|
||||
@@ -986,7 +986,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv,
|
||||
V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_tuner)) {
|
||||
ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_tuner, v);
|
||||
} else if (v->index == 1) {
|
||||
strlcpy(v->name, "RF: <unknown>", sizeof(v->name));
|
||||
strscpy(v->name, "RF: <unknown>", sizeof(v->name));
|
||||
v->type = V4L2_TUNER_RF;
|
||||
v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
|
||||
v->rangelow = 50000000;
|
||||
@@ -1133,7 +1133,7 @@ static int rtl2832_sdr_enum_fmt_sdr_cap(struct file *file, void *priv,
|
||||
if (f->index >= dev->num_formats)
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(f->description, formats[f->index].name, sizeof(f->description));
|
||||
strscpy(f->description, formats[f->index].name, sizeof(f->description));
|
||||
f->pixelformat = formats[f->index].pixelformat;
|
||||
|
||||
return 0;
|
||||
|
@@ -912,7 +912,7 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
|
||||
state->frontend.demodulator_priv = state;
|
||||
|
||||
/* create tuner i2c adapter */
|
||||
strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
|
||||
strscpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
|
||||
sizeof(state->tuner_i2c_adapter.name));
|
||||
state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
|
||||
state->tuner_i2c_adapter.algo_data = NULL;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for the ST STV0910 DVB-S/S2 demodulator.
|
||||
*
|
||||
@@ -1839,4 +1840,4 @@ EXPORT_SYMBOL_GPL(stv0910_attach);
|
||||
|
||||
MODULE_DESCRIPTION("ST STV0910 multistandard frontend driver");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for the ST STV0910 DVB-S/S2 demodulator.
|
||||
*
|
||||
* Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* developed for Digital Devices GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _STV0910_H_
|
||||
#define _STV0910_H_
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* @DVB-S/DVB-S2 STMicroelectronics STV0900 register definitions
|
||||
* Author Manfred Voelkel, August 2013
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for the ST STV6111 tuner
|
||||
*
|
||||
@@ -11,7 +12,6 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -687,4 +687,4 @@ EXPORT_SYMBOL_GPL(stv6111_attach);
|
||||
|
||||
MODULE_DESCRIPTION("ST STV6111 satellite tuner driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for the ST STV6111 tuner
|
||||
*
|
||||
* Copyright (C) 2014 Digital Devices GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _STV6111_H_
|
||||
#define _STV6111_H_
|
||||
|
||||
|
@@ -781,7 +781,7 @@ static int tc90522_probe(struct i2c_client *client,
|
||||
adap->owner = THIS_MODULE;
|
||||
adap->algo = &tc90522_tuner_i2c_algo;
|
||||
adap->dev.parent = &client->dev;
|
||||
strlcpy(adap->name, "tc90522_sub", sizeof(adap->name));
|
||||
strscpy(adap->name, "tc90522_sub", sizeof(adap->name));
|
||||
i2c_set_adapdata(adap, state);
|
||||
ret = i2c_add_adapter(adap);
|
||||
if (ret < 0)
|
||||
|
@@ -525,7 +525,7 @@ struct dvb_frontend *ts2020_attach(struct dvb_frontend *fe,
|
||||
pdata.attach_in_use = true;
|
||||
|
||||
memset(&board_info, 0, sizeof(board_info));
|
||||
strlcpy(board_info.type, "ts2020", I2C_NAME_SIZE);
|
||||
strscpy(board_info.type, "ts2020", I2C_NAME_SIZE);
|
||||
board_info.addr = config->tuner_address;
|
||||
board_info.platform_data = &pdata;
|
||||
client = i2c_new_device(i2c, &board_info);
|
||||
|
@@ -499,7 +499,8 @@ static int zd1301_demod_probe(struct platform_device *pdev)
|
||||
goto err_kfree;
|
||||
|
||||
/* Create I2C adapter */
|
||||
strlcpy(dev->adapter.name, "ZyDAS ZD1301 demod", sizeof(dev->adapter.name));
|
||||
strscpy(dev->adapter.name, "ZyDAS ZD1301 demod",
|
||||
sizeof(dev->adapter.name));
|
||||
dev->adapter.algo = &zd1301_demod_i2c_algorithm;
|
||||
dev->adapter.algo_data = NULL;
|
||||
dev->adapter.dev.parent = pdev->dev.parent;
|
||||
|
@@ -288,8 +288,9 @@ struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
|
||||
state->id = state->id & 0x0f;
|
||||
switch (state->id) {
|
||||
case ID_ZL10039:
|
||||
strcpy(fe->ops.tuner_ops.info.name,
|
||||
"Zarlink ZL10039 DVB-S tuner");
|
||||
strscpy(fe->ops.tuner_ops.info.name,
|
||||
"Zarlink ZL10039 DVB-S tuner",
|
||||
sizeof(fe->ops.tuner_ops.info.name));
|
||||
break;
|
||||
default:
|
||||
dprintk("Chip ID=%x does not match a known type\n", state->id);
|
||||
|
@@ -247,7 +247,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
|
||||
dev_err(fdtv->device, "no frontend for model type %d\n",
|
||||
fdtv->type);
|
||||
}
|
||||
strcpy(fi->name, name);
|
||||
strscpy(fi->name, name, sizeof(fi->name));
|
||||
|
||||
fdtv->fe.dvb = &fdtv->adapter;
|
||||
fdtv->fe.sec_priv = fdtv;
|
||||
|
@@ -614,6 +614,28 @@ config VIDEO_IMX274
|
||||
This is a V4L2 sensor driver for the Sony IMX274
|
||||
CMOS image sensor.
|
||||
|
||||
config VIDEO_IMX319
|
||||
tristate "Sony IMX319 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
IMX319 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx319.
|
||||
|
||||
config VIDEO_IMX355
|
||||
tristate "Sony IMX355 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
help
|
||||
This is a Video4Linux2 sensor driver for the Sony
|
||||
IMX355 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called imx355.
|
||||
|
||||
config VIDEO_OV2640
|
||||
tristate "OmniVision OV2640 sensor support"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
@@ -747,6 +769,7 @@ config VIDEO_OV772X
|
||||
tristate "OmniVision OV772x sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select REGMAP_SCCB
|
||||
---help---
|
||||
This is a Video4Linux2 sensor driver for the OmniVision
|
||||
OV772x camera.
|
||||
@@ -786,6 +809,7 @@ config VIDEO_OV7740
|
||||
config VIDEO_OV9650
|
||||
tristate "OmniVision OV9650/OV9652 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
select REGMAP_SCCB
|
||||
---help---
|
||||
This is a V4L2 sensor driver for the Omnivision
|
||||
OV9650 and OV9652 camera sensors.
|
||||
|
@@ -108,5 +108,7 @@ obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
|
||||
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o
|
||||
obj-$(CONFIG_VIDEO_IMX258) += imx258.o
|
||||
obj-$(CONFIG_VIDEO_IMX274) += imx274.o
|
||||
obj-$(CONFIG_VIDEO_IMX319) += imx319.o
|
||||
obj-$(CONFIG_VIDEO_IMX355) += imx355.o
|
||||
|
||||
obj-$(CONFIG_SDR_MAX2175) += max2175.o
|
||||
|
@@ -317,7 +317,7 @@ static int ad5820_probe(struct i2c_client *client,
|
||||
v4l2_i2c_subdev_init(&coil->subdev, client, &ad5820_ops);
|
||||
coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
coil->subdev.internal_ops = &ad5820_internal_ops;
|
||||
strcpy(coil->subdev.name, "ad5820 focus");
|
||||
strscpy(coil->subdev.name, "ad5820 focus", sizeof(coil->subdev.name));
|
||||
|
||||
ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
|
||||
if (ret < 0)
|
||||
|
@@ -1,19 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* adv7180.c Analog Devices ADV7180 video decoder driver
|
||||
* Copyright (c) 2009 Intel Corporation
|
||||
* Copyright (C) 2013 Cogent Embedded, Inc.
|
||||
* Copyright (C) 2013 Renesas Solutions Corp.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
@@ -761,7 +752,7 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
|
||||
struct adv7180_state *state = to_state(sd);
|
||||
|
||||
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
|
||||
cfg->type = V4L2_MBUS_CSI2;
|
||||
cfg->type = V4L2_MBUS_CSI2_DPHY;
|
||||
cfg->flags = V4L2_MBUS_CSI2_1_LANE |
|
||||
V4L2_MBUS_CSI2_CHANNEL_0 |
|
||||
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
|
||||
|
@@ -1,13 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Driver for Analog Devices ADV748X 8 channel analog front end (AFE) receiver
|
||||
* with standard definition processor (SDP)
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@@ -286,7 +282,7 @@ static int adv748x_afe_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = adv748x_txb_power(state, enable);
|
||||
ret = adv748x_tx_power(&state->txb, enable);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
|
||||
|
@@ -1,13 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Driver for Analog Devices ADV748X HDMI receiver with AFE
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Authors:
|
||||
* Koji Matsuoka <koji.matsuoka.xm@renesas.com>
|
||||
* Niklas Söderlund <niklas.soderlund@ragnatech.se>
|
||||
@@ -285,18 +281,23 @@ static const struct adv748x_reg_value adv748x_power_down_txb_1lane[] = {
|
||||
|
||||
{ADV748X_PAGE_TXB, 0x31, 0x82}, /* ADI Required Write */
|
||||
{ADV748X_PAGE_TXB, 0x1e, 0x00}, /* ADI Required Write */
|
||||
{ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 4-lane MIPI */
|
||||
{ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */
|
||||
{ADV748X_PAGE_TXB, 0xda, 0x01}, /* i2c_mipi_pll_en - 1'b1 */
|
||||
{ADV748X_PAGE_TXB, 0xc1, 0x3b}, /* ADI Required Write */
|
||||
|
||||
{ADV748X_PAGE_EOR, 0xff, 0xff} /* End of register table */
|
||||
};
|
||||
|
||||
int adv748x_txa_power(struct adv748x_state *state, bool on)
|
||||
int adv748x_tx_power(struct adv748x_csi2 *tx, bool on)
|
||||
{
|
||||
struct adv748x_state *state = tx->state;
|
||||
const struct adv748x_reg_value *reglist;
|
||||
int val;
|
||||
|
||||
val = txa_read(state, ADV748X_CSI_FS_AS_LS);
|
||||
if (!is_tx_enabled(tx))
|
||||
return 0;
|
||||
|
||||
val = tx_read(tx, ADV748X_CSI_FS_AS_LS);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
@@ -309,31 +310,13 @@ int adv748x_txa_power(struct adv748x_state *state, bool on)
|
||||
"Enabling with unknown bit set");
|
||||
|
||||
if (on)
|
||||
return adv748x_write_regs(state, adv748x_power_up_txa_4lane);
|
||||
reglist = is_txa(tx) ? adv748x_power_up_txa_4lane :
|
||||
adv748x_power_up_txb_1lane;
|
||||
else
|
||||
reglist = is_txa(tx) ? adv748x_power_down_txa_4lane :
|
||||
adv748x_power_down_txb_1lane;
|
||||
|
||||
return adv748x_write_regs(state, adv748x_power_down_txa_4lane);
|
||||
}
|
||||
|
||||
int adv748x_txb_power(struct adv748x_state *state, bool on)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = txb_read(state, ADV748X_CSI_FS_AS_LS);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/*
|
||||
* This test against BIT(6) is not documented by the datasheet, but was
|
||||
* specified in the downstream driver.
|
||||
* Track with a WARN_ONCE to determine if it is ever set by HW.
|
||||
*/
|
||||
WARN_ONCE((on && val & ADV748X_CSI_FS_AS_LS_UNKNOWN),
|
||||
"Enabling with unknown bit set");
|
||||
|
||||
if (on)
|
||||
return adv748x_write_regs(state, adv748x_power_up_txb_1lane);
|
||||
|
||||
return adv748x_write_regs(state, adv748x_power_down_txb_1lane);
|
||||
return adv748x_write_regs(state, reglist);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
@@ -399,8 +382,6 @@ static const struct adv748x_reg_value adv748x_init_txa_4lane[] = {
|
||||
|
||||
{ADV748X_PAGE_IO, 0x0c, 0xe0}, /* Enable LLC_DLL & Double LLC Timing */
|
||||
{ADV748X_PAGE_IO, 0x0e, 0xdd}, /* LLC/PIX/SPI PINS TRISTATED AUD */
|
||||
/* Outputs Enabled */
|
||||
{ADV748X_PAGE_IO, 0x10, 0xa0}, /* Enable 4-lane CSI Tx & Pixel Port */
|
||||
|
||||
{ADV748X_PAGE_TXA, 0x00, 0x84}, /* Enable 4-lane MIPI */
|
||||
{ADV748X_PAGE_TXA, 0x00, 0xa4}, /* Set Auto DPHY Timing */
|
||||
@@ -454,10 +435,6 @@ static const struct adv748x_reg_value adv748x_init_txb_1lane[] = {
|
||||
{ADV748X_PAGE_SDP, 0x31, 0x12}, /* ADI Required Write */
|
||||
{ADV748X_PAGE_SDP, 0xe6, 0x4f}, /* V bit end pos manually in NTSC */
|
||||
|
||||
/* Enable 1-Lane MIPI Tx, */
|
||||
/* enable pixel output and route SD through Pixel port */
|
||||
{ADV748X_PAGE_IO, 0x10, 0x70},
|
||||
|
||||
{ADV748X_PAGE_TXB, 0x00, 0x81}, /* Enable 1-lane MIPI */
|
||||
{ADV748X_PAGE_TXB, 0x00, 0xa1}, /* Set Auto DPHY Timing */
|
||||
{ADV748X_PAGE_TXB, 0xd2, 0x40}, /* ADI Required Write */
|
||||
@@ -482,6 +459,7 @@ static const struct adv748x_reg_value adv748x_init_txb_1lane[] = {
|
||||
static int adv748x_reset(struct adv748x_state *state)
|
||||
{
|
||||
int ret;
|
||||
u8 regval = 0;
|
||||
|
||||
ret = adv748x_write_regs(state, adv748x_sw_reset);
|
||||
if (ret < 0)
|
||||
@@ -496,22 +474,24 @@ static int adv748x_reset(struct adv748x_state *state)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
adv748x_txa_power(state, 0);
|
||||
adv748x_tx_power(&state->txa, 0);
|
||||
|
||||
/* Init and power down TXB */
|
||||
ret = adv748x_write_regs(state, adv748x_init_txb_1lane);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
adv748x_txb_power(state, 0);
|
||||
adv748x_tx_power(&state->txb, 0);
|
||||
|
||||
/* Disable chip powerdown & Enable HDMI Rx block */
|
||||
io_write(state, ADV748X_IO_PD, ADV748X_IO_PD_RX_EN);
|
||||
|
||||
/* Enable 4-lane CSI Tx & Pixel Port */
|
||||
io_write(state, ADV748X_IO_10, ADV748X_IO_10_CSI4_EN |
|
||||
ADV748X_IO_10_CSI1_EN |
|
||||
ADV748X_IO_10_PIX_OUT_EN);
|
||||
/* Conditionally enable TXa and TXb. */
|
||||
if (is_tx_enabled(&state->txa))
|
||||
regval |= ADV748X_IO_10_CSI4_EN;
|
||||
if (is_tx_enabled(&state->txb))
|
||||
regval |= ADV748X_IO_10_CSI1_EN;
|
||||
io_write(state, ADV748X_IO_10, regval);
|
||||
|
||||
/* Use vid_std and v_freq as freerun resolution for CP */
|
||||
cp_clrset(state, ADV748X_CP_CLMP_POS, ADV748X_CP_CLMP_POS_DIS_AUTO,
|
||||
@@ -569,7 +549,8 @@ static int adv748x_parse_dt(struct adv748x_state *state)
|
||||
{
|
||||
struct device_node *ep_np = NULL;
|
||||
struct of_endpoint ep;
|
||||
bool found = false;
|
||||
bool out_found = false;
|
||||
bool in_found = false;
|
||||
|
||||
for_each_endpoint_of_node(state->dev->of_node, ep_np) {
|
||||
of_graph_parse_endpoint(ep_np, &ep);
|
||||
@@ -592,10 +573,17 @@ static int adv748x_parse_dt(struct adv748x_state *state)
|
||||
of_node_get(ep_np);
|
||||
state->endpoints[ep.port] = ep_np;
|
||||
|
||||
found = true;
|
||||
/*
|
||||
* At least one input endpoint and one output endpoint shall
|
||||
* be defined.
|
||||
*/
|
||||
if (ep.port < ADV748X_PORT_TXA)
|
||||
in_found = true;
|
||||
else
|
||||
out_found = true;
|
||||
}
|
||||
|
||||
return found ? 0 : -ENODEV;
|
||||
return in_found && out_found ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static void adv748x_dt_cleanup(struct adv748x_state *state)
|
||||
@@ -627,6 +615,17 @@ static int adv748x_probe(struct i2c_client *client,
|
||||
state->i2c_clients[ADV748X_PAGE_IO] = client;
|
||||
i2c_set_clientdata(client, state);
|
||||
|
||||
/*
|
||||
* We can not use container_of to get back to the state with two TXs;
|
||||
* Initialize the TXs's fields unconditionally on the endpoint
|
||||
* presence to access them later.
|
||||
*/
|
||||
state->txa.state = state->txb.state = state;
|
||||
state->txa.page = ADV748X_PAGE_TXA;
|
||||
state->txb.page = ADV748X_PAGE_TXB;
|
||||
state->txa.port = ADV748X_PORT_TXA;
|
||||
state->txb.port = ADV748X_PORT_TXB;
|
||||
|
||||
/* Discover and process ports declared by the Device tree endpoints */
|
||||
ret = adv748x_parse_dt(state);
|
||||
if (ret) {
|
||||
@@ -755,4 +754,4 @@ module_i2c_driver(adv748x_driver);
|
||||
|
||||
MODULE_AUTHOR("Kieran Bingham <kieran.bingham@ideasonboard.com>");
|
||||
MODULE_DESCRIPTION("ADV748X video decoder");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -1,12 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Driver for Analog Devices ADV748X CSI-2 Transmitter
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -18,11 +14,6 @@
|
||||
|
||||
#include "adv748x.h"
|
||||
|
||||
static bool is_txa(struct adv748x_csi2 *tx)
|
||||
{
|
||||
return tx == &tx->state->txa;
|
||||
}
|
||||
|
||||
static int adv748x_csi2_set_virtual_channel(struct adv748x_csi2 *tx,
|
||||
unsigned int vc)
|
||||
{
|
||||
@@ -87,15 +78,15 @@ static int adv748x_csi2_registered(struct v4l2_subdev *sd)
|
||||
*
|
||||
* Link HDMI->TXA, and AFE->TXB directly.
|
||||
*/
|
||||
if (is_txa(tx)) {
|
||||
if (is_txa(tx) && is_hdmi_enabled(state))
|
||||
return adv748x_csi2_register_link(tx, sd->v4l2_dev,
|
||||
&state->hdmi.sd,
|
||||
ADV748X_HDMI_SOURCE);
|
||||
} else {
|
||||
if (!is_txa(tx) && is_afe_enabled(state))
|
||||
return adv748x_csi2_register_link(tx, sd->v4l2_dev,
|
||||
&state->afe.sd,
|
||||
ADV748X_AFE_SOURCE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_internal_ops adv748x_csi2_internal_ops = {
|
||||
@@ -266,19 +257,10 @@ static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
|
||||
|
||||
int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
|
||||
{
|
||||
struct device_node *ep;
|
||||
int ret;
|
||||
|
||||
/* We can not use container_of to get back to the state with two TXs */
|
||||
tx->state = state;
|
||||
tx->page = is_txa(tx) ? ADV748X_PAGE_TXA : ADV748X_PAGE_TXB;
|
||||
|
||||
ep = state->endpoints[is_txa(tx) ? ADV748X_PORT_TXA : ADV748X_PORT_TXB];
|
||||
if (!ep) {
|
||||
adv_err(state, "No endpoint found for %s\n",
|
||||
is_txa(tx) ? "txa" : "txb");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (!is_tx_enabled(tx))
|
||||
return 0;
|
||||
|
||||
/* Initialise the virtual channel */
|
||||
adv748x_csi2_set_virtual_channel(tx, 0);
|
||||
@@ -288,7 +270,7 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx)
|
||||
is_txa(tx) ? "txa" : "txb");
|
||||
|
||||
/* Ensure that matching is based upon the endpoint fwnodes */
|
||||
tx->sd.fwnode = of_fwnode_handle(ep);
|
||||
tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]);
|
||||
|
||||
/* Register internal ops for incremental subdev registration */
|
||||
tx->sd.internal_ops = &adv748x_csi2_internal_ops;
|
||||
@@ -321,6 +303,9 @@ err_free_media:
|
||||
|
||||
void adv748x_csi2_cleanup(struct adv748x_csi2 *tx)
|
||||
{
|
||||
if (!is_tx_enabled(tx))
|
||||
return;
|
||||
|
||||
v4l2_async_unregister_subdev(&tx->sd);
|
||||
media_entity_cleanup(&tx->sd.entity);
|
||||
v4l2_ctrl_handler_free(&tx->ctrl_hdl);
|
||||
|
@@ -1,12 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Driver for Analog Devices ADV748X HDMI receiver and Component Processor (CP)
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -362,7 +358,7 @@ static int adv748x_hdmi_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
|
||||
mutex_lock(&state->mutex);
|
||||
|
||||
ret = adv748x_txa_power(state, enable);
|
||||
ret = adv748x_tx_power(&state->txa, enable);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
|
@@ -1,13 +1,9 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Driver for Analog Devices ADV748X video decoder and HDMI receiver
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Authors:
|
||||
* Koji Matsuoka <koji.matsuoka.xm@renesas.com>
|
||||
* Niklas Söderlund <niklas.soderlund@ragnatech.se>
|
||||
@@ -82,6 +78,7 @@ struct adv748x_csi2 {
|
||||
struct adv748x_state *state;
|
||||
struct v4l2_mbus_framefmt format;
|
||||
unsigned int page;
|
||||
unsigned int port;
|
||||
|
||||
struct media_pad pads[ADV748X_CSI2_NR_PADS];
|
||||
struct v4l2_ctrl_handler ctrl_hdl;
|
||||
@@ -91,6 +88,18 @@ struct adv748x_csi2 {
|
||||
|
||||
#define notifier_to_csi2(n) container_of(n, struct adv748x_csi2, notifier)
|
||||
#define adv748x_sd_to_csi2(sd) container_of(sd, struct adv748x_csi2, sd)
|
||||
#define is_tx_enabled(_tx) ((_tx)->state->endpoints[(_tx)->port] != NULL)
|
||||
#define is_txa(_tx) ((_tx) == &(_tx)->state->txa)
|
||||
#define is_afe_enabled(_state) \
|
||||
((_state)->endpoints[ADV748X_PORT_AIN0] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN1] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN2] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN3] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN4] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN5] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN6] != NULL || \
|
||||
(_state)->endpoints[ADV748X_PORT_AIN7] != NULL)
|
||||
#define is_hdmi_enabled(_state) ((_state)->endpoints[ADV748X_PORT_HDMI] != NULL)
|
||||
|
||||
enum adv748x_hdmi_pads {
|
||||
ADV748X_HDMI_SINK,
|
||||
@@ -376,9 +385,6 @@ int adv748x_write_block(struct adv748x_state *state, int client_page,
|
||||
#define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v)
|
||||
#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v)
|
||||
|
||||
#define txa_read(s, r) adv748x_read(s, ADV748X_PAGE_TXA, r)
|
||||
#define txb_read(s, r) adv748x_read(s, ADV748X_PAGE_TXB, r)
|
||||
|
||||
#define tx_read(t, r) adv748x_read(t->state, t->page, r)
|
||||
#define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v)
|
||||
|
||||
@@ -398,8 +404,7 @@ void adv748x_subdev_init(struct v4l2_subdev *sd, struct adv748x_state *state,
|
||||
int adv748x_register_subdevs(struct adv748x_state *state,
|
||||
struct v4l2_device *v4l2_dev);
|
||||
|
||||
int adv748x_txa_power(struct adv748x_state *state, bool on);
|
||||
int adv748x_txb_power(struct adv748x_state *state, bool on);
|
||||
int adv748x_tx_power(struct adv748x_csi2 *tx, bool on);
|
||||
|
||||
int adv748x_afe_init(struct adv748x_afe *afe);
|
||||
void adv748x_afe_cleanup(struct adv748x_afe *afe);
|
||||
|
@@ -1355,10 +1355,10 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
|
||||
state->xfer_func = format->format.xfer_func;
|
||||
|
||||
switch (format->format.colorspace) {
|
||||
case V4L2_COLORSPACE_ADOBERGB:
|
||||
case V4L2_COLORSPACE_OPRGB:
|
||||
c = HDMI_COLORIMETRY_EXTENDED;
|
||||
ec = y ? HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601 :
|
||||
HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB;
|
||||
ec = y ? HDMI_EXTENDED_COLORIMETRY_OPYCC_601 :
|
||||
HDMI_EXTENDED_COLORIMETRY_OPRGB;
|
||||
break;
|
||||
case V4L2_COLORSPACE_SMPTE170M:
|
||||
c = y ? HDMI_COLORIMETRY_ITU_601 : HDMI_COLORIMETRY_NONE;
|
||||
|
@@ -2284,8 +2284,10 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
state->aspect_ratio.numerator = 16;
|
||||
state->aspect_ratio.denominator = 9;
|
||||
|
||||
if (!state->edid.present)
|
||||
if (!state->edid.present) {
|
||||
state->edid.blocks = 0;
|
||||
cec_phys_addr_invalidate(state->cec_adap);
|
||||
}
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: clear EDID pad %d, edid.present = 0x%x\n",
|
||||
__func__, edid->pad, state->edid.present);
|
||||
@@ -2295,8 +2297,8 @@ static int adv76xx_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
|
||||
edid->blocks = 2;
|
||||
return -E2BIG;
|
||||
}
|
||||
pa = cec_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc);
|
||||
err = cec_phys_addr_validate(pa, &pa, NULL);
|
||||
pa = v4l2_get_edid_phys_addr(edid->edid, edid->blocks * 128, &spa_loc);
|
||||
err = v4l2_phys_addr_validate(pa, &pa, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2474,7 +2476,7 @@ static int adv76xx_log_status(struct v4l2_subdev *sd)
|
||||
"YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
|
||||
"xvYCC Bt.601", "xvYCC Bt.709",
|
||||
"YCbCr Bt.601 (0-255)", "YCbCr Bt.709 (0-255)",
|
||||
"sYCC", "Adobe YCC 601", "AdobeRGB", "invalid", "invalid",
|
||||
"sYCC", "opYCC 601", "opRGB", "invalid", "invalid",
|
||||
"invalid", "invalid", "invalid"
|
||||
};
|
||||
static const char * const rgb_quantization_range_txt[] = {
|
||||
@@ -3093,7 +3095,7 @@ MODULE_DEVICE_TABLE(of, adv76xx_of_id);
|
||||
|
||||
static int adv76xx_parse_dt(struct adv76xx_state *state)
|
||||
{
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
|
||||
struct device_node *endpoint;
|
||||
struct device_node *np;
|
||||
unsigned int flags;
|
||||
|
@@ -786,11 +786,13 @@ static int edid_write_hdmi_segment(struct v4l2_subdev *sd, u8 port)
|
||||
/* Disable I2C access to internal EDID ram from HDMI DDC ports */
|
||||
rep_write_and_or(sd, 0x77, 0xf3, 0x00);
|
||||
|
||||
if (!state->hdmi_edid.present)
|
||||
if (!state->hdmi_edid.present) {
|
||||
cec_phys_addr_invalidate(state->cec_adap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pa = cec_get_edid_phys_addr(edid, 256, &spa_loc);
|
||||
err = cec_phys_addr_validate(pa, &pa, NULL);
|
||||
pa = v4l2_get_edid_phys_addr(edid, 256, &spa_loc);
|
||||
err = v4l2_phys_addr_validate(pa, &pa, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1525,6 +1527,7 @@ static void adv7842_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
|
||||
v4l2_find_dv_timings_cap(timings, adv7842_get_dv_timings_cap(sd),
|
||||
is_digital_input(sd) ? 250000 : 1000000,
|
||||
adv7842_check_dv_timings, NULL);
|
||||
timings->bt.flags |= V4L2_DV_FL_CAN_DETECT_REDUCED_FPS;
|
||||
}
|
||||
|
||||
static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
|
||||
@@ -1596,6 +1599,14 @@ static int adv7842_query_dv_timings(struct v4l2_subdev *sd,
|
||||
bt->il_vbackporch = 0;
|
||||
}
|
||||
adv7842_fill_optional_dv_timings_fields(sd, timings);
|
||||
if ((timings->bt.flags & V4L2_DV_FL_CAN_REDUCE_FPS) &&
|
||||
freq < bt->pixelclock) {
|
||||
u32 reduced_freq = ((u32)bt->pixelclock / 1001) * 1000;
|
||||
u32 delta_freq = abs(freq - reduced_freq);
|
||||
|
||||
if (delta_freq < ((u32)bt->pixelclock - reduced_freq) / 2)
|
||||
timings->bt.flags |= V4L2_DV_FL_REDUCED_FPS;
|
||||
}
|
||||
} else {
|
||||
/* find format
|
||||
* Since LCVS values are inaccurate [REF_03, p. 339-340],
|
||||
|
@@ -136,7 +136,6 @@ static int ak881x_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = 720;
|
||||
|
@@ -149,7 +149,7 @@ static int cs53l32a_probe(struct i2c_client *client,
|
||||
return -EIO;
|
||||
|
||||
if (!id)
|
||||
strlcpy(client->name, "cs53l32a", sizeof(client->name));
|
||||
strscpy(client->name, "cs53l32a", sizeof(client->name));
|
||||
|
||||
v4l_info(client, "chip found @ 0x%x (%s)\n",
|
||||
client->addr << 1, client->adapter->name);
|
||||
|
@@ -701,10 +701,8 @@ static int cx25840_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
|
||||
if (v > IR_MAX_DURATION)
|
||||
v = IR_MAX_DURATION;
|
||||
|
||||
init_ir_raw_event(&p->ir_core_data);
|
||||
p->ir_core_data.pulse = u;
|
||||
p->ir_core_data.duration = v;
|
||||
p->ir_core_data.timeout = w;
|
||||
p->ir_core_data = (struct ir_raw_event)
|
||||
{ .pulse = u, .duration = v, .timeout = w };
|
||||
|
||||
v4l2_dbg(2, ir_debug, sd, "rx read: %10u ns %s %s\n",
|
||||
v, u ? "mark" : "space", w ? "(timed out)" : "");
|
||||
|
@@ -169,8 +169,9 @@ static int dw9714_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
||||
dw9714_subdev_cleanup(dw9714_dev);
|
||||
dev_err(&client->dev, "Probe failed: %d\n", rval);
|
||||
v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm);
|
||||
media_entity_cleanup(&dw9714_dev->sd.entity);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@@ -218,7 +218,8 @@ static int dw9807_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
||||
dw9807_subdev_cleanup(dw9807_dev);
|
||||
v4l2_ctrl_handler_free(&dw9807_dev->ctrls_vcm);
|
||||
media_entity_cleanup(&dw9807_dev->sd.entity);
|
||||
|
||||
return rval;
|
||||
}
|
||||
@@ -229,7 +230,6 @@ static int dw9807_remove(struct i2c_client *client)
|
||||
struct dw9807_device *dw9807_dev = sd_to_dw9807_vcm(sd);
|
||||
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
|
||||
dw9807_subdev_cleanup(dw9807_dev);
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* imx274.c - IMX274 CMOS Image Sensor driver
|
||||
*
|
||||
@@ -6,18 +7,6 @@
|
||||
* Leon Luo <leonl@leopardimaging.com>
|
||||
* Edwin Zou <edwinz@leopardimaging.com>
|
||||
* Luca Ceresoli <luca@lucaceresoli.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* 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/clk.h>
|
||||
@@ -76,7 +65,7 @@
|
||||
*/
|
||||
#define IMX274_MIN_EXPOSURE_TIME (4 * 260 / 72)
|
||||
|
||||
#define IMX274_DEFAULT_MODE IMX274_BINNING_OFF
|
||||
#define IMX274_DEFAULT_BINNING IMX274_BINNING_OFF
|
||||
#define IMX274_MAX_WIDTH (3840)
|
||||
#define IMX274_MAX_HEIGHT (2160)
|
||||
#define IMX274_MAX_FRAME_RATE (120)
|
||||
@@ -178,7 +167,7 @@ enum imx274_binning {
|
||||
* @nocpiop: Number of clocks per internal offset period (see "Integration Time
|
||||
* in Each Readout Drive Mode (CSI-2)" in the datasheet)
|
||||
*/
|
||||
struct imx274_frmfmt {
|
||||
struct imx274_mode {
|
||||
const struct reg_8 *init_regs;
|
||||
unsigned int bin_ratio;
|
||||
int min_frame_len;
|
||||
@@ -349,20 +338,14 @@ static const struct reg_8 imx274_mode5_1280x720_raw10[] = {
|
||||
*/
|
||||
static const struct reg_8 imx274_start_1[] = {
|
||||
{IMX274_STANDBY_REG, 0x12},
|
||||
{IMX274_TABLE_END, 0x00}
|
||||
};
|
||||
|
||||
/*
|
||||
* imx274 second step register configuration for
|
||||
* starting stream
|
||||
*/
|
||||
static const struct reg_8 imx274_start_2[] = {
|
||||
{0x3120, 0xF0}, /* clock settings */
|
||||
{0x3121, 0x00}, /* clock settings */
|
||||
{0x3122, 0x02}, /* clock settings */
|
||||
{0x3129, 0x9C}, /* clock settings */
|
||||
{0x312A, 0x02}, /* clock settings */
|
||||
{0x312D, 0x02}, /* clock settings */
|
||||
/* PLRD: clock settings */
|
||||
{0x3120, 0xF0},
|
||||
{0x3121, 0x00},
|
||||
{0x3122, 0x02},
|
||||
{0x3129, 0x9C},
|
||||
{0x312A, 0x02},
|
||||
{0x312D, 0x02},
|
||||
|
||||
{0x310B, 0x00},
|
||||
|
||||
@@ -407,20 +390,20 @@ static const struct reg_8 imx274_start_2[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* imx274 third step register configuration for
|
||||
* imx274 second step register configuration for
|
||||
* starting stream
|
||||
*/
|
||||
static const struct reg_8 imx274_start_3[] = {
|
||||
static const struct reg_8 imx274_start_2[] = {
|
||||
{IMX274_STANDBY_REG, 0x00},
|
||||
{0x303E, 0x02}, /* SYS_MODE = 2 */
|
||||
{IMX274_TABLE_END, 0x00}
|
||||
};
|
||||
|
||||
/*
|
||||
* imx274 forth step register configuration for
|
||||
* imx274 third step register configuration for
|
||||
* starting stream
|
||||
*/
|
||||
static const struct reg_8 imx274_start_4[] = {
|
||||
static const struct reg_8 imx274_start_3[] = {
|
||||
{0x30F4, 0x00},
|
||||
{0x3018, 0xA2}, /* XHS VHS OUTUPT */
|
||||
{IMX274_TABLE_END, 0x00}
|
||||
@@ -459,7 +442,7 @@ static const struct reg_8 imx274_tp_regs[] = {
|
||||
};
|
||||
|
||||
/* nocpiop happens to be the same number for the implemented modes */
|
||||
static const struct imx274_frmfmt imx274_formats[] = {
|
||||
static const struct imx274_mode imx274_modes[] = {
|
||||
{
|
||||
/* mode 1, 4K */
|
||||
.bin_ratio = 1,
|
||||
@@ -532,7 +515,7 @@ struct stimx274 {
|
||||
struct regmap *regmap;
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct mutex lock; /* mutex lock for operations */
|
||||
const struct imx274_frmfmt *mode;
|
||||
const struct imx274_mode *mode;
|
||||
};
|
||||
|
||||
#define IMX274_ROUND(dim, step, flags) \
|
||||
@@ -665,6 +648,41 @@ static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a multibyte register.
|
||||
*
|
||||
* Uses a bulk read where possible.
|
||||
*
|
||||
* @priv: Pointer to device structure
|
||||
* @addr: Address of the LSB register. Other registers must be
|
||||
* consecutive, least-to-most significant.
|
||||
* @val: Pointer to store the register value (cpu endianness)
|
||||
* @nbytes: Number of bytes to read (range: [1..3]).
|
||||
* Other bytes are zet to 0.
|
||||
*
|
||||
* Return: 0 on success, errors otherwise
|
||||
*/
|
||||
static int imx274_read_mbreg(struct stimx274 *priv, u16 addr, u32 *val,
|
||||
size_t nbytes)
|
||||
{
|
||||
__le32 val_le = 0;
|
||||
int err;
|
||||
|
||||
err = regmap_bulk_read(priv->regmap, addr, &val_le, nbytes);
|
||||
if (err) {
|
||||
dev_err(&priv->client->dev,
|
||||
"%s : i2c bulk read failed, %x (%zu bytes)\n",
|
||||
__func__, addr, nbytes);
|
||||
} else {
|
||||
*val = le32_to_cpu(val_le);
|
||||
dev_dbg(&priv->client->dev,
|
||||
"%s : addr 0x%x, val=0x%x (%zu bytes)\n",
|
||||
__func__, addr, *val, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a multibyte register.
|
||||
*
|
||||
@@ -674,7 +692,7 @@ static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
|
||||
* @addr: Address of the LSB register. Other registers must be
|
||||
* consecutive, least-to-most significant.
|
||||
* @val: Value to be written to the register (cpu endianness)
|
||||
* @nbytes: Number of bits to write (range: [1..3])
|
||||
* @nbytes: Number of bytes to write (range: [1..3])
|
||||
*/
|
||||
static int imx274_write_mbreg(struct stimx274 *priv, u16 addr, u32 val,
|
||||
size_t nbytes)
|
||||
@@ -708,10 +726,6 @@ static int imx274_mode_regs(struct stimx274 *priv)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = imx274_write_table(priv, imx274_start_2);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = imx274_write_table(priv, priv->mode->init_regs);
|
||||
|
||||
return err;
|
||||
@@ -733,7 +747,7 @@ static int imx274_start_stream(struct stimx274 *priv)
|
||||
* give it 1 extra ms for margin
|
||||
*/
|
||||
msleep_range(11);
|
||||
err = imx274_write_table(priv, imx274_start_3);
|
||||
err = imx274_write_table(priv, imx274_start_2);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -743,7 +757,7 @@ static int imx274_start_stream(struct stimx274 *priv)
|
||||
* give it 1 extra ms for margin
|
||||
*/
|
||||
msleep_range(8);
|
||||
err = imx274_write_table(priv, imx274_start_4);
|
||||
err = imx274_write_table(priv, imx274_start_3);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -881,7 +895,7 @@ static int __imx274_change_compose(struct stimx274 *imx274,
|
||||
const struct v4l2_rect *cur_crop;
|
||||
struct v4l2_mbus_framefmt *tgt_fmt;
|
||||
unsigned int i;
|
||||
const struct imx274_frmfmt *best_mode = &imx274_formats[0];
|
||||
const struct imx274_mode *best_mode = &imx274_modes[0];
|
||||
int best_goodness = INT_MIN;
|
||||
|
||||
if (which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
@@ -892,8 +906,8 @@ static int __imx274_change_compose(struct stimx274 *imx274,
|
||||
tgt_fmt = &imx274->format;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(imx274_formats); i++) {
|
||||
unsigned int ratio = imx274_formats[i].bin_ratio;
|
||||
for (i = 0; i < ARRAY_SIZE(imx274_modes); i++) {
|
||||
unsigned int ratio = imx274_modes[i].bin_ratio;
|
||||
|
||||
int goodness = imx274_binning_goodness(
|
||||
imx274,
|
||||
@@ -903,7 +917,7 @@ static int __imx274_change_compose(struct stimx274 *imx274,
|
||||
|
||||
if (goodness >= best_goodness) {
|
||||
best_goodness = goodness;
|
||||
best_mode = &imx274_formats[i];
|
||||
best_mode = &imx274_modes[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1323,7 +1337,7 @@ static int imx274_s_stream(struct v4l2_subdev *sd, int on)
|
||||
|
||||
dev_dbg(&imx274->client->dev, "%s : %s, mode index = %td\n", __func__,
|
||||
on ? "Stream Start" : "Stream Stop",
|
||||
imx274->mode - &imx274_formats[0]);
|
||||
imx274->mode - &imx274_modes[0]);
|
||||
|
||||
mutex_lock(&imx274->lock);
|
||||
|
||||
@@ -1387,37 +1401,17 @@ fail:
|
||||
static int imx274_get_frame_length(struct stimx274 *priv, u32 *val)
|
||||
{
|
||||
int err;
|
||||
u16 svr;
|
||||
u32 svr;
|
||||
u32 vmax;
|
||||
u8 reg_val[3];
|
||||
|
||||
/* svr */
|
||||
err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]);
|
||||
err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]);
|
||||
err = imx274_read_mbreg(priv, IMX274_VMAX_REG_3, &vmax, 3);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
|
||||
|
||||
/* vmax */
|
||||
err = imx274_read_reg(priv, IMX274_VMAX_REG_3, ®_val[0]);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = imx274_read_reg(priv, IMX274_VMAX_REG_2, ®_val[1]);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = imx274_read_reg(priv, IMX274_VMAX_REG_1, ®_val[2]);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
vmax = ((reg_val[2] & IMX274_MASK_LSB_3_BITS) << IMX274_SHIFT_16_BITS)
|
||||
+ (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
|
||||
|
||||
*val = vmax * (svr + 1);
|
||||
|
||||
return 0;
|
||||
@@ -1598,8 +1592,7 @@ fail:
|
||||
static int imx274_set_exposure(struct stimx274 *priv, int val)
|
||||
{
|
||||
int err;
|
||||
u16 hmax;
|
||||
u8 reg_val[2];
|
||||
u32 hmax;
|
||||
u32 coarse_time; /* exposure time in unit of line (HMAX)*/
|
||||
|
||||
dev_dbg(&priv->client->dev,
|
||||
@@ -1607,14 +1600,10 @@ static int imx274_set_exposure(struct stimx274 *priv, int val)
|
||||
|
||||
/* step 1: convert input exposure_time (val) into number of 1[HMAX] */
|
||||
|
||||
/* obtain HMAX value */
|
||||
err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]);
|
||||
err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
|
||||
if (err)
|
||||
goto fail;
|
||||
err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]);
|
||||
if (err)
|
||||
goto fail;
|
||||
hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
|
||||
|
||||
if (hmax == 0) {
|
||||
err = -EINVAL;
|
||||
goto fail;
|
||||
@@ -1749,9 +1738,8 @@ static int imx274_set_frame_interval(struct stimx274 *priv,
|
||||
{
|
||||
int err;
|
||||
u32 frame_length, req_frame_rate;
|
||||
u16 svr;
|
||||
u16 hmax;
|
||||
u8 reg_val[2];
|
||||
u32 svr;
|
||||
u32 hmax;
|
||||
|
||||
dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d",
|
||||
__func__, frame_interval.numerator,
|
||||
@@ -1779,25 +1767,17 @@ static int imx274_set_frame_interval(struct stimx274 *priv,
|
||||
* frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX
|
||||
*/
|
||||
|
||||
/* SVR */
|
||||
err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]);
|
||||
err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
|
||||
if (err)
|
||||
goto fail;
|
||||
err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]);
|
||||
if (err)
|
||||
goto fail;
|
||||
svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
|
||||
|
||||
dev_dbg(&priv->client->dev,
|
||||
"%s : register SVR = %d\n", __func__, svr);
|
||||
|
||||
/* HMAX */
|
||||
err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]);
|
||||
err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
|
||||
if (err)
|
||||
goto fail;
|
||||
err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]);
|
||||
if (err)
|
||||
goto fail;
|
||||
hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0];
|
||||
|
||||
dev_dbg(&priv->client->dev,
|
||||
"%s : register HMAX = %d\n", __func__, hmax);
|
||||
|
||||
@@ -1871,7 +1851,7 @@ static int imx274_probe(struct i2c_client *client,
|
||||
mutex_init(&imx274->lock);
|
||||
|
||||
/* initialize format */
|
||||
imx274->mode = &imx274_formats[IMX274_DEFAULT_MODE];
|
||||
imx274->mode = &imx274_modes[IMX274_DEFAULT_BINNING];
|
||||
imx274->crop.width = IMX274_MAX_WIDTH;
|
||||
imx274->crop.height = IMX274_MAX_HEIGHT;
|
||||
imx274->format.width = imx274->crop.width / imx274->mode->bin_ratio;
|
||||
@@ -1895,7 +1875,6 @@ static int imx274_probe(struct i2c_client *client,
|
||||
imx274->client = client;
|
||||
sd = &imx274->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops);
|
||||
strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
|
||||
/* initialize subdev media pad */
|
||||
|
2560
drivers/media/i2c/imx319.c
Normal file
2560
drivers/media/i2c/imx319.c
Normal file
文件差異過大導致無法顯示
Load Diff
1860
drivers/media/i2c/imx355.c
Normal file
1860
drivers/media/i2c/imx355.c
Normal file
文件差異過大導致無法顯示
Load Diff
@@ -362,7 +362,8 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
|
||||
|
||||
v4l2_i2c_subdev_init(&flash->subdev_led[led_no], client, &lm3560_ops);
|
||||
flash->subdev_led[led_no].flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
strcpy(flash->subdev_led[led_no].name, led_name);
|
||||
strscpy(flash->subdev_led[led_no].name, led_name,
|
||||
sizeof(flash->subdev_led[led_no].name));
|
||||
rval = lm3560_init_controls(flash, led_no);
|
||||
if (rval)
|
||||
goto err_out;
|
||||
|
@@ -278,7 +278,8 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
|
||||
|
||||
v4l2_i2c_subdev_init(&flash->subdev_led, client, &lm3646_ops);
|
||||
flash->subdev_led.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
strcpy(flash->subdev_led.name, LM3646_NAME);
|
||||
strscpy(flash->subdev_led.name, LM3646_NAME,
|
||||
sizeof(flash->subdev_led.name));
|
||||
rval = lm3646_init_controls(flash);
|
||||
if (rval)
|
||||
goto err_out;
|
||||
|
@@ -987,7 +987,8 @@ static int m5mols_probe(struct i2c_client *client,
|
||||
|
||||
sd = &info->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
|
||||
strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
|
||||
/* Static name; NEVER use in new drivers! */
|
||||
strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
||||
sd->internal_ops = &m5mols_subdev_internal_ops;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Maxim Integrated MAX2175 RF to Bits tuner driver
|
||||
*
|
||||
@@ -6,15 +7,6 @@
|
||||
*
|
||||
* Copyright (C) 2016 Maxim Integrated Products
|
||||
* Copyright (C) 2017 Renesas Electronics Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@@ -1165,7 +1157,7 @@ static int max2175_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
|
||||
if (vt->index > 0)
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(vt->name, "RF", sizeof(vt->name));
|
||||
strscpy(vt->name, "RF", sizeof(vt->name));
|
||||
vt->type = V4L2_TUNER_RF;
|
||||
vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
|
||||
vt->rangelow = ctx->bands_rf->rangelow;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Maxim Integrated MAX2175 RF to Bits tuner driver
|
||||
*
|
||||
* This driver & most of the hard coded values are based on the reference
|
||||
@@ -6,15 +7,6 @@
|
||||
*
|
||||
* Copyright (C) 2016 Maxim Integrated Products
|
||||
* Copyright (C) 2017 Renesas Electronics Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __MAX2175_H__
|
||||
|
@@ -688,7 +688,7 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
#endif
|
||||
|
||||
if (!id)
|
||||
strlcpy(client->name, "msp3400", sizeof(client->name));
|
||||
strscpy(client->name, "msp3400", sizeof(client->name));
|
||||
|
||||
if (msp_reset(client) == -1) {
|
||||
dev_dbg_lvl(&client->dev, 1, msp_debug, "msp3400 not found\n");
|
||||
@@ -703,8 +703,10 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
v4l2_i2c_subdev_init(sd, client, &msp_ops);
|
||||
|
||||
#if defined(CONFIG_MEDIA_CONTROLLER)
|
||||
state->pads[IF_AUD_DEC_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
|
||||
state->pads[IF_AUD_DEC_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[MSP3400_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
|
||||
state->pads[MSP3400_PAD_IF_INPUT].sig_type = PAD_SIGNAL_AUDIO;
|
||||
state->pads[MSP3400_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
|
||||
state->pads[MSP3400_PAD_OUT].sig_type = PAD_SIGNAL_AUDIO;
|
||||
|
||||
sd->entity.function = MEDIA_ENT_F_IF_AUD_DECODER;
|
||||
|
||||
|
@@ -52,6 +52,12 @@ extern int msp_standard;
|
||||
extern bool msp_dolby;
|
||||
extern int msp_stereo_thresh;
|
||||
|
||||
enum msp3400_pads {
|
||||
MSP3400_PAD_IF_INPUT,
|
||||
MSP3400_PAD_OUT,
|
||||
MSP3400_NUM_PADS
|
||||
};
|
||||
|
||||
struct msp_state {
|
||||
struct v4l2_subdev sd;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
@@ -106,7 +112,7 @@ struct msp_state {
|
||||
unsigned int watch_stereo:1;
|
||||
|
||||
#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
|
||||
struct media_pad pads[IF_AUD_DEC_PAD_NUM_PADS];
|
||||
struct media_pad pads[MSP3400_NUM_PADS];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -445,7 +445,6 @@ static int mt9m111_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.left = MT9M111_MIN_DARK_COLS;
|
||||
sel->r.top = MT9M111_MIN_DARK_ROWS;
|
||||
sel->r.width = MT9M111_MAX_WIDTH;
|
||||
|
@@ -888,12 +888,6 @@ static int mt9t112_get_selection(struct v4l2_subdev *sd,
|
||||
sel->r.width = MAX_WIDTH;
|
||||
sel->r.height = MAX_HEIGHT;
|
||||
return 0;
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = VGA_WIDTH;
|
||||
sel->r.height = VGA_HEIGHT;
|
||||
return 0;
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r = priv->frame;
|
||||
return 0;
|
||||
|
@@ -989,7 +989,7 @@ static struct mt9v032_platform_data *
|
||||
mt9v032_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct mt9v032_platform_data *pdata = NULL;
|
||||
struct v4l2_fwnode_endpoint endpoint;
|
||||
struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
|
||||
struct device_node *np;
|
||||
struct property *prop;
|
||||
|
||||
|
@@ -720,7 +720,8 @@ static int noon010_probe(struct i2c_client *client,
|
||||
mutex_init(&info->lock);
|
||||
sd = &info->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &noon010_ops);
|
||||
strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
|
||||
/* Static name; NEVER use in new drivers! */
|
||||
strscpy(sd->name, MODULE_NAME, sizeof(sd->name));
|
||||
|
||||
sd->internal_ops = &noon010_subdev_internal_ops;
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
@@ -1230,7 +1230,7 @@ static int ov13858_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
* Applying V4L2 control value only happens
|
||||
* when power is up for streaming
|
||||
*/
|
||||
if (pm_runtime_get_if_in_use(&client->dev) <= 0)
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
@@ -1735,10 +1735,9 @@ static int ov13858_probe(struct i2c_client *client,
|
||||
* Device is already turned on by i2c-core with ACPI domain PM.
|
||||
* Enable runtime PM and turn off the device.
|
||||
*/
|
||||
pm_runtime_get_noresume(&client->dev);
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1761,14 +1760,7 @@ static int ov13858_remove(struct i2c_client *client)
|
||||
media_entity_cleanup(&sd->entity);
|
||||
ov13858_free_controls(ov13858);
|
||||
|
||||
/*
|
||||
* Disable runtime PM but keep the device turned on.
|
||||
* i2c-core with ACPI domain PM will turn off the device.
|
||||
*/
|
||||
pm_runtime_get_sync(&client->dev);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1010,7 +1010,6 @@ static int ov2640_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
|
@@ -1347,8 +1347,9 @@ static struct ov2659_platform_data *
|
||||
ov2659_get_pdata(struct i2c_client *client)
|
||||
{
|
||||
struct ov2659_platform_data *pdata;
|
||||
struct v4l2_fwnode_endpoint *bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
|
||||
struct device_node *endpoint;
|
||||
int ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
|
||||
return client->dev.platform_data;
|
||||
@@ -1357,8 +1358,9 @@ ov2659_get_pdata(struct i2c_client *client)
|
||||
if (!endpoint)
|
||||
return NULL;
|
||||
|
||||
bus_cfg = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint));
|
||||
if (IS_ERR(bus_cfg)) {
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(endpoint),
|
||||
&bus_cfg);
|
||||
if (ret) {
|
||||
pdata = NULL;
|
||||
goto done;
|
||||
}
|
||||
@@ -1367,17 +1369,17 @@ ov2659_get_pdata(struct i2c_client *client)
|
||||
if (!pdata)
|
||||
goto done;
|
||||
|
||||
if (!bus_cfg->nr_of_link_frequencies) {
|
||||
if (!bus_cfg.nr_of_link_frequencies) {
|
||||
dev_err(&client->dev,
|
||||
"link-frequencies property not found or too many\n");
|
||||
pdata = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
pdata->link_frequency = bus_cfg->link_frequencies[0];
|
||||
pdata->link_frequency = bus_cfg.link_frequencies[0];
|
||||
|
||||
done:
|
||||
v4l2_fwnode_endpoint_free(bus_cfg);
|
||||
v4l2_fwnode_endpoint_free(&bus_cfg);
|
||||
of_node_put(endpoint);
|
||||
return pdata;
|
||||
}
|
||||
|
@@ -926,7 +926,7 @@ static int ov2680_mode_init(struct ov2680_dev *sensor)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov2680_v4l2_init(struct ov2680_dev *sensor)
|
||||
static int ov2680_v4l2_register(struct ov2680_dev *sensor)
|
||||
{
|
||||
const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
|
||||
struct ov2680_ctrls *ctrls = &sensor->ctrls;
|
||||
@@ -1088,26 +1088,20 @@ static int ov2680_probe(struct i2c_client *client)
|
||||
|
||||
mutex_init(&sensor->lock);
|
||||
|
||||
ret = ov2680_v4l2_init(sensor);
|
||||
ret = ov2680_check_id(sensor);
|
||||
if (ret < 0)
|
||||
goto lock_destroy;
|
||||
|
||||
ret = ov2680_check_id(sensor);
|
||||
ret = ov2680_v4l2_register(sensor);
|
||||
if (ret < 0)
|
||||
goto error_cleanup;
|
||||
goto lock_destroy;
|
||||
|
||||
dev_info(dev, "ov2680 init correctly\n");
|
||||
|
||||
return 0;
|
||||
|
||||
error_cleanup:
|
||||
dev_err(dev, "ov2680 init fail: %d\n", ret);
|
||||
|
||||
media_entity_cleanup(&sensor->sd.entity);
|
||||
v4l2_async_unregister_subdev(&sensor->sd);
|
||||
v4l2_ctrl_handler_free(&sensor->ctrls.handler);
|
||||
|
||||
lock_destroy:
|
||||
dev_err(dev, "ov2680 init fail: %d\n", ret);
|
||||
mutex_destroy(&sensor->lock);
|
||||
|
||||
return ret;
|
||||
|
@@ -549,7 +549,7 @@ static int ov2685_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pm_runtime_get_if_in_use(&client->dev) <= 0)
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@@ -223,8 +223,10 @@ struct ov5640_dev {
|
||||
int power_count;
|
||||
|
||||
struct v4l2_mbus_framefmt fmt;
|
||||
bool pending_fmt_change;
|
||||
|
||||
const struct ov5640_mode_info *current_mode;
|
||||
const struct ov5640_mode_info *last_mode;
|
||||
enum ov5640_frame_rate current_fr;
|
||||
struct v4l2_fract frame_interval;
|
||||
|
||||
@@ -255,7 +257,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
|
||||
* should be identified and removed to speed register load time
|
||||
* over i2c.
|
||||
*/
|
||||
|
||||
/* YUV422 UYVY VGA@30fps */
|
||||
static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
|
||||
{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
|
||||
{0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
|
||||
@@ -286,10 +288,10 @@ static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
|
||||
{0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
|
||||
{0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
|
||||
{0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
|
||||
{0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
|
||||
{0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
|
||||
{0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
|
||||
{0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
|
||||
{0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
|
||||
{0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0},
|
||||
{0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
|
||||
{0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
|
||||
{0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
|
||||
@@ -606,7 +608,7 @@ static const struct reg_value ov5640_setting_15fps_720P_1280_720[] = {
|
||||
{0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
|
||||
{0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
|
||||
{0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
|
||||
{0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x02, 0, 0},
|
||||
{0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0},
|
||||
{0x4407, 0x04, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
|
||||
{0x3824, 0x04, 0, 0}, {0x5001, 0x83, 0, 0},
|
||||
};
|
||||
@@ -908,6 +910,26 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
|
||||
}
|
||||
|
||||
/* download ov5640 settings to sensor through i2c */
|
||||
static int ov5640_set_timings(struct ov5640_dev *sensor,
|
||||
const struct ov5640_mode_info *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
|
||||
}
|
||||
|
||||
static int ov5640_load_regs(struct ov5640_dev *sensor,
|
||||
const struct ov5640_mode_info *mode)
|
||||
{
|
||||
@@ -935,7 +957,13 @@ static int ov5640_load_regs(struct ov5640_dev *sensor,
|
||||
usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ov5640_set_timings(sensor, mode);
|
||||
}
|
||||
|
||||
static int ov5640_set_autoexposure(struct ov5640_dev *sensor, bool on)
|
||||
{
|
||||
return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
|
||||
BIT(0), on ? 0 : BIT(0));
|
||||
}
|
||||
|
||||
/* read exposure, in number of line periods */
|
||||
@@ -994,6 +1022,18 @@ static int ov5640_get_gain(struct ov5640_dev *sensor)
|
||||
return gain & 0x3ff;
|
||||
}
|
||||
|
||||
static int ov5640_set_gain(struct ov5640_dev *sensor, int gain)
|
||||
{
|
||||
return ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
|
||||
(u16)gain & 0x3ff);
|
||||
}
|
||||
|
||||
static int ov5640_set_autogain(struct ov5640_dev *sensor, bool on)
|
||||
{
|
||||
return ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
|
||||
BIT(1), on ? 0 : BIT(1));
|
||||
}
|
||||
|
||||
static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
|
||||
{
|
||||
int ret;
|
||||
@@ -1102,12 +1142,25 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ov5640_mod_reg(sensor, OV5640_REG_MIPI_CTRL00, BIT(5),
|
||||
on ? 0 : BIT(5));
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00,
|
||||
on ? 0x00 : 0x70);
|
||||
/*
|
||||
* Enable/disable the MIPI interface
|
||||
*
|
||||
* 0x300e = on ? 0x45 : 0x40
|
||||
*
|
||||
* FIXME: the sensor manual (version 2.03) reports
|
||||
* [7:5] = 000 : 1 data lane mode
|
||||
* [7:5] = 001 : 2 data lanes mode
|
||||
* But this settings do not work, while the following ones
|
||||
* have been validated for 2 data lanes mode.
|
||||
*
|
||||
* [7:5] = 010 : 2 data lanes mode
|
||||
* [4] = 0 : Power up MIPI HS Tx
|
||||
* [3] = 0 : Power up MIPI LS Rx
|
||||
* [2] = 1/0 : MIPI interface enable/disable
|
||||
* [1:0] = 01/00: FIXME: 'debug'
|
||||
*/
|
||||
ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00,
|
||||
on ? 0x45 : 0x40);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1331,7 +1384,7 @@ static int ov5640_set_ae_target(struct ov5640_dev *sensor, int target)
|
||||
return ov5640_write_reg(sensor, OV5640_REG_AEC_CTRL1F, fast_low);
|
||||
}
|
||||
|
||||
static int ov5640_binning_on(struct ov5640_dev *sensor)
|
||||
static int ov5640_get_binning(struct ov5640_dev *sensor)
|
||||
{
|
||||
u8 temp;
|
||||
int ret;
|
||||
@@ -1339,8 +1392,8 @@ static int ov5640_binning_on(struct ov5640_dev *sensor)
|
||||
ret = ov5640_read_reg(sensor, OV5640_REG_TIMING_TC_REG21, &temp);
|
||||
if (ret)
|
||||
return ret;
|
||||
temp &= 0xfe;
|
||||
return temp ? 1 : 0;
|
||||
|
||||
return temp & BIT(0);
|
||||
}
|
||||
|
||||
static int ov5640_set_binning(struct ov5640_dev *sensor, bool enable)
|
||||
@@ -1385,30 +1438,6 @@ static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
|
||||
return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp);
|
||||
}
|
||||
|
||||
static int ov5640_set_timings(struct ov5640_dev *sensor,
|
||||
const struct ov5640_mode_info *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ov5640_mode_info *
|
||||
ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
|
||||
int width, int height, bool nearest)
|
||||
@@ -1450,7 +1479,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
prev_shutter = ret;
|
||||
ret = ov5640_binning_on(sensor);
|
||||
ret = ov5640_get_binning(sensor);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret && mode->id != OV5640_MODE_720P_1280_720 &&
|
||||
@@ -1571,7 +1600,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
|
||||
}
|
||||
|
||||
/* set capture gain */
|
||||
ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.gain, cap_gain16);
|
||||
ret = ov5640_set_gain(sensor, cap_gain16);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -1584,7 +1613,7 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
|
||||
}
|
||||
|
||||
/* set exposure */
|
||||
return __v4l2_ctrl_s_ctrl(sensor->ctrls.exposure, cap_shutter);
|
||||
return ov5640_set_exposure(sensor, cap_shutter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1592,53 +1621,45 @@ static int ov5640_set_mode_exposure_calc(struct ov5640_dev *sensor,
|
||||
* change mode directly
|
||||
*/
|
||||
static int ov5640_set_mode_direct(struct ov5640_dev *sensor,
|
||||
const struct ov5640_mode_info *mode,
|
||||
s32 exposure)
|
||||
const struct ov5640_mode_info *mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mode->reg_data)
|
||||
return -EINVAL;
|
||||
|
||||
/* Write capture setting */
|
||||
ret = ov5640_load_regs(sensor, mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* turn auto gain/exposure back on for direct mode */
|
||||
ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_gain, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_exp, exposure);
|
||||
return ov5640_load_regs(sensor, mode);
|
||||
}
|
||||
|
||||
static int ov5640_set_mode(struct ov5640_dev *sensor,
|
||||
const struct ov5640_mode_info *orig_mode)
|
||||
static int ov5640_set_mode(struct ov5640_dev *sensor)
|
||||
{
|
||||
const struct ov5640_mode_info *mode = sensor->current_mode;
|
||||
const struct ov5640_mode_info *orig_mode = sensor->last_mode;
|
||||
enum ov5640_downsize_mode dn_mode, orig_dn_mode;
|
||||
s32 exposure;
|
||||
bool auto_gain = sensor->ctrls.auto_gain->val == 1;
|
||||
bool auto_exp = sensor->ctrls.auto_exp->val == V4L2_EXPOSURE_AUTO;
|
||||
int ret;
|
||||
|
||||
dn_mode = mode->dn_mode;
|
||||
orig_dn_mode = orig_mode->dn_mode;
|
||||
|
||||
/* auto gain and exposure must be turned off when changing modes */
|
||||
ret = __v4l2_ctrl_s_ctrl(sensor->ctrls.auto_gain, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (auto_gain) {
|
||||
ret = ov5640_set_autogain(sensor, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
exposure = sensor->ctrls.auto_exp->val;
|
||||
ret = ov5640_set_exposure(sensor, V4L2_EXPOSURE_MANUAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (auto_exp) {
|
||||
ret = ov5640_set_autoexposure(sensor, false);
|
||||
if (ret)
|
||||
goto restore_auto_gain;
|
||||
}
|
||||
|
||||
if ((dn_mode == SUBSAMPLING && orig_dn_mode == SCALING) ||
|
||||
(dn_mode == SCALING && orig_dn_mode == SUBSAMPLING)) {
|
||||
/*
|
||||
* change between subsampling and scaling
|
||||
* go through exposure calucation
|
||||
* go through exposure calculation
|
||||
*/
|
||||
ret = ov5640_set_mode_exposure_calc(sensor, mode);
|
||||
} else {
|
||||
@@ -1646,15 +1667,16 @@ static int ov5640_set_mode(struct ov5640_dev *sensor,
|
||||
* change inside subsampling or scaling
|
||||
* download firmware directly
|
||||
*/
|
||||
ret = ov5640_set_mode_direct(sensor, mode, exposure);
|
||||
ret = ov5640_set_mode_direct(sensor, mode);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto restore_auto_exp_gain;
|
||||
|
||||
ret = ov5640_set_timings(sensor, mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* restore auto gain and exposure */
|
||||
if (auto_gain)
|
||||
ov5640_set_autogain(sensor, true);
|
||||
if (auto_exp)
|
||||
ov5640_set_autoexposure(sensor, true);
|
||||
|
||||
ret = ov5640_set_binning(sensor, dn_mode != SCALING);
|
||||
if (ret < 0)
|
||||
@@ -1673,8 +1695,18 @@ static int ov5640_set_mode(struct ov5640_dev *sensor,
|
||||
return ret;
|
||||
|
||||
sensor->pending_mode_change = false;
|
||||
sensor->last_mode = mode;
|
||||
|
||||
return 0;
|
||||
|
||||
restore_auto_exp_gain:
|
||||
if (auto_exp)
|
||||
ov5640_set_autoexposure(sensor, true);
|
||||
restore_auto_gain:
|
||||
if (auto_gain)
|
||||
ov5640_set_autogain(sensor, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov5640_set_framefmt(struct ov5640_dev *sensor,
|
||||
@@ -1689,6 +1721,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
|
||||
ret = ov5640_load_regs(sensor, &ov5640_mode_init_data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
sensor->last_mode = &ov5640_mode_init_data;
|
||||
|
||||
ret = ov5640_mod_reg(sensor, OV5640_REG_SYS_ROOT_DIVIDER, 0x3f,
|
||||
(ilog2(OV5640_SCLK2X_ROOT_DIVIDER_DEFAULT) << 2) |
|
||||
@@ -1697,7 +1730,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
|
||||
return ret;
|
||||
|
||||
/* now restore the last capture mode */
|
||||
ret = ov5640_set_mode(sensor, &ov5640_mode_init_data);
|
||||
ret = ov5640_set_mode(sensor);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1786,23 +1819,69 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
|
||||
if (ret)
|
||||
goto power_off;
|
||||
|
||||
if (sensor->ep.bus_type == V4L2_MBUS_CSI2) {
|
||||
/*
|
||||
* start streaming briefly followed by stream off in
|
||||
* order to coax the clock lane into LP-11 state.
|
||||
*/
|
||||
ret = ov5640_set_stream_mipi(sensor, true);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
usleep_range(1000, 2000);
|
||||
ret = ov5640_set_stream_mipi(sensor, false);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
/* We're done here for DVP bus, while CSI-2 needs setup. */
|
||||
if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Power up MIPI HS Tx and LS Rx; 2 data lanes mode
|
||||
*
|
||||
* 0x300e = 0x40
|
||||
* [7:5] = 010 : 2 data lanes mode (see FIXME note in
|
||||
* "ov5640_set_stream_mipi()")
|
||||
* [4] = 0 : Power up MIPI HS Tx
|
||||
* [3] = 0 : Power up MIPI LS Rx
|
||||
* [2] = 0 : MIPI interface disabled
|
||||
*/
|
||||
ret = ov5640_write_reg(sensor,
|
||||
OV5640_REG_IO_MIPI_CTRL00, 0x40);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
|
||||
/*
|
||||
* Gate clock and set LP11 in 'no packets mode' (idle)
|
||||
*
|
||||
* 0x4800 = 0x24
|
||||
* [5] = 1 : Gate clock when 'no packets'
|
||||
* [2] = 1 : MIPI bus in LP11 when 'no packets'
|
||||
*/
|
||||
ret = ov5640_write_reg(sensor,
|
||||
OV5640_REG_MIPI_CTRL00, 0x24);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
|
||||
/*
|
||||
* Set data lanes and clock in LP11 when 'sleeping'
|
||||
*
|
||||
* 0x3019 = 0x70
|
||||
* [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping'
|
||||
* [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping'
|
||||
* [4] = 1 : MIPI clock lane in LP11 when 'sleeping'
|
||||
*/
|
||||
ret = ov5640_write_reg(sensor,
|
||||
OV5640_REG_PAD_OUTPUT00, 0x70);
|
||||
if (ret)
|
||||
goto power_off;
|
||||
|
||||
/* Give lanes some time to coax into LP11 state. */
|
||||
usleep_range(500, 1000);
|
||||
|
||||
} else {
|
||||
if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
|
||||
/* Reset MIPI bus settings to their default values. */
|
||||
ov5640_write_reg(sensor,
|
||||
OV5640_REG_IO_MIPI_CTRL00, 0x58);
|
||||
ov5640_write_reg(sensor,
|
||||
OV5640_REG_MIPI_CTRL00, 0x04);
|
||||
ov5640_write_reg(sensor,
|
||||
OV5640_REG_PAD_OUTPUT00, 0x00);
|
||||
}
|
||||
|
||||
return 0;
|
||||
ov5640_set_power_off(sensor);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
power_off:
|
||||
ov5640_set_power_off(sensor);
|
||||
return ret;
|
||||
@@ -1968,9 +2047,12 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
|
||||
|
||||
if (new_mode != sensor->current_mode) {
|
||||
sensor->current_mode = new_mode;
|
||||
sensor->fmt = *mbus_fmt;
|
||||
sensor->pending_mode_change = true;
|
||||
}
|
||||
if (mbus_fmt->code != sensor->fmt.code) {
|
||||
sensor->fmt = *mbus_fmt;
|
||||
sensor->pending_fmt_change = true;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&sensor->lock);
|
||||
return ret;
|
||||
@@ -2137,20 +2219,20 @@ static int ov5640_set_ctrl_white_balance(struct ov5640_dev *sensor, int awb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
|
||||
static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor,
|
||||
enum v4l2_exposure_auto_type auto_exposure)
|
||||
{
|
||||
struct ov5640_ctrls *ctrls = &sensor->ctrls;
|
||||
bool auto_exposure = (exp == V4L2_EXPOSURE_AUTO);
|
||||
bool auto_exp = (auto_exposure == V4L2_EXPOSURE_AUTO);
|
||||
int ret = 0;
|
||||
|
||||
if (ctrls->auto_exp->is_new) {
|
||||
ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
|
||||
BIT(0), auto_exposure ? 0 : BIT(0));
|
||||
ret = ov5640_set_autoexposure(sensor, auto_exp);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!auto_exposure && ctrls->exposure->is_new) {
|
||||
if (!auto_exp && ctrls->exposure->is_new) {
|
||||
u16 max_exp;
|
||||
|
||||
ret = ov5640_read_reg16(sensor, OV5640_REG_AEC_PK_VTS,
|
||||
@@ -2170,25 +2252,19 @@ static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, int auto_gain)
|
||||
static int ov5640_set_ctrl_gain(struct ov5640_dev *sensor, bool auto_gain)
|
||||
{
|
||||
struct ov5640_ctrls *ctrls = &sensor->ctrls;
|
||||
int ret = 0;
|
||||
|
||||
if (ctrls->auto_gain->is_new) {
|
||||
ret = ov5640_mod_reg(sensor, OV5640_REG_AEC_PK_MANUAL,
|
||||
BIT(1),
|
||||
ctrls->auto_gain->val ? 0 : BIT(1));
|
||||
ret = ov5640_set_autogain(sensor, auto_gain);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!auto_gain && ctrls->gain->is_new) {
|
||||
u16 gain = (u16)ctrls->gain->val;
|
||||
|
||||
ret = ov5640_write_reg16(sensor, OV5640_REG_AEC_PK_REAL_GAIN,
|
||||
gain & 0x3ff);
|
||||
}
|
||||
if (!auto_gain && ctrls->gain->is_new)
|
||||
ret = ov5640_set_gain(sensor, ctrls->gain->val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2261,16 +2337,12 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
if (!ctrl->val)
|
||||
return 0;
|
||||
val = ov5640_get_gain(sensor);
|
||||
if (val < 0)
|
||||
return val;
|
||||
sensor->ctrls.gain->val = val;
|
||||
break;
|
||||
case V4L2_CID_EXPOSURE_AUTO:
|
||||
if (ctrl->val == V4L2_EXPOSURE_MANUAL)
|
||||
return 0;
|
||||
val = ov5640_get_exposure(sensor);
|
||||
if (val < 0)
|
||||
return val;
|
||||
@@ -2501,8 +2573,6 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
|
||||
if (frame_rate < 0)
|
||||
frame_rate = OV5640_15_FPS;
|
||||
|
||||
sensor->current_fr = frame_rate;
|
||||
sensor->frame_interval = fi->interval;
|
||||
mode = ov5640_find_mode(sensor, frame_rate, mode->hact,
|
||||
mode->vact, true);
|
||||
if (!mode) {
|
||||
@@ -2510,7 +2580,10 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mode != sensor->current_mode) {
|
||||
if (mode != sensor->current_mode ||
|
||||
frame_rate != sensor->current_fr) {
|
||||
sensor->current_fr = frame_rate;
|
||||
sensor->frame_interval = fi->interval;
|
||||
sensor->current_mode = mode;
|
||||
sensor->pending_mode_change = true;
|
||||
}
|
||||
@@ -2541,16 +2614,19 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
|
||||
if (sensor->streaming == !enable) {
|
||||
if (enable && sensor->pending_mode_change) {
|
||||
ret = ov5640_set_mode(sensor, sensor->current_mode);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = ov5640_set_framefmt(sensor, &sensor->fmt);
|
||||
ret = ov5640_set_mode(sensor);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
|
||||
if (enable && sensor->pending_fmt_change) {
|
||||
ret = ov5640_set_framefmt(sensor, &sensor->fmt);
|
||||
if (ret)
|
||||
goto out;
|
||||
sensor->pending_fmt_change = false;
|
||||
}
|
||||
|
||||
if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
|
||||
ret = ov5640_set_stream_mipi(sensor, enable);
|
||||
else
|
||||
ret = ov5640_set_stream_dvp(sensor, enable);
|
||||
@@ -2642,9 +2718,14 @@ static int ov5640_probe(struct i2c_client *client,
|
||||
return -ENOMEM;
|
||||
|
||||
sensor->i2c_client = client;
|
||||
|
||||
/*
|
||||
* default init sequence initialize sensor to
|
||||
* YUV422 UYVY VGA@30fps
|
||||
*/
|
||||
fmt = &sensor->fmt;
|
||||
fmt->code = ov5640_formats[0].code;
|
||||
fmt->colorspace = ov5640_formats[0].colorspace;
|
||||
fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
|
||||
fmt->colorspace = V4L2_COLORSPACE_SRGB;
|
||||
fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
|
||||
fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
|
||||
fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
|
||||
@@ -2656,7 +2737,7 @@ static int ov5640_probe(struct i2c_client *client,
|
||||
sensor->current_fr = OV5640_30_FPS;
|
||||
sensor->current_mode =
|
||||
&ov5640_mode_data[OV5640_30_FPS][OV5640_MODE_VGA_640_480];
|
||||
sensor->pending_mode_change = true;
|
||||
sensor->last_mode = sensor->current_mode;
|
||||
|
||||
sensor->ae_target = 52;
|
||||
|
||||
|
@@ -1127,7 +1127,7 @@ static int ov5645_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ov5645->ep.bus_type != V4L2_MBUS_CSI2) {
|
||||
if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
|
||||
dev_err(dev, "invalid bus type, must be CSI2\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@@ -532,7 +532,7 @@ static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = {
|
||||
|
||||
static int ov5647_parse_dt(struct device_node *np)
|
||||
{
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
|
||||
struct device_node *ep;
|
||||
|
||||
int ret;
|
||||
|
@@ -2016,7 +2016,7 @@ static int ov5670_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
}
|
||||
|
||||
/* V4L2 controls values will be applied only when power is already up */
|
||||
if (pm_runtime_get_if_in_use(&client->dev) <= 0)
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
@@ -2504,10 +2504,9 @@ static int ov5670_probe(struct i2c_client *client)
|
||||
* Device is already turned on by i2c-core with ACPI domain PM.
|
||||
* Enable runtime PM and turn off the device.
|
||||
*/
|
||||
pm_runtime_get_noresume(&client->dev);
|
||||
pm_runtime_set_active(&client->dev);
|
||||
pm_runtime_enable(&client->dev);
|
||||
pm_runtime_put(&client->dev);
|
||||
pm_runtime_idle(&client->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -2536,14 +2535,7 @@ static int ov5670_remove(struct i2c_client *client)
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
mutex_destroy(&ov5670->mutex);
|
||||
|
||||
/*
|
||||
* Disable runtime PM but keep the device turned on.
|
||||
* i2c-core with ACPI domain PM will turn off the device.
|
||||
*/
|
||||
pm_runtime_get_sync(&client->dev);
|
||||
pm_runtime_disable(&client->dev);
|
||||
pm_runtime_set_suspended(&client->dev);
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1110,7 +1110,7 @@ static int ov5695_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pm_runtime_get_if_in_use(&client->dev) <= 0)
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@@ -449,7 +449,6 @@ static int ov6650_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.left = DEF_HSTRT << 1;
|
||||
sel->r.top = DEF_VSTRT << 1;
|
||||
sel->r.width = W_CIF;
|
||||
|
@@ -1279,9 +1279,9 @@ static int ov7251_probe(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ov7251->ep.bus_type != V4L2_MBUS_CSI2) {
|
||||
if (ov7251->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
|
||||
dev_err(dev, "invalid bus type (%u), must be CSI2 (%u)\n",
|
||||
ov7251->ep.bus_type, V4L2_MBUS_CSI2);
|
||||
ov7251->ep.bus_type, V4L2_MBUS_CSI2_DPHY);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@@ -1728,7 +1728,7 @@ static int ov7670_parse_dt(struct device *dev,
|
||||
struct ov7670_info *info)
|
||||
{
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
struct v4l2_fwnode_endpoint bus_cfg;
|
||||
struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 };
|
||||
struct fwnode_handle *ep;
|
||||
int ret;
|
||||
|
||||
@@ -1808,17 +1808,24 @@ static int ov7670_probe(struct i2c_client *client,
|
||||
info->pclk_hb_disable = true;
|
||||
}
|
||||
|
||||
info->clk = devm_clk_get(&client->dev, "xclk");
|
||||
if (IS_ERR(info->clk))
|
||||
return PTR_ERR(info->clk);
|
||||
ret = clk_prepare_enable(info->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
info->clk = devm_clk_get(&client->dev, "xclk"); /* optional */
|
||||
if (IS_ERR(info->clk)) {
|
||||
ret = PTR_ERR(info->clk);
|
||||
if (ret == -ENOENT)
|
||||
info->clk = NULL;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
if (info->clk) {
|
||||
ret = clk_prepare_enable(info->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
info->clock_speed = clk_get_rate(info->clk) / 1000000;
|
||||
if (info->clock_speed < 10 || info->clock_speed > 48) {
|
||||
ret = -EINVAL;
|
||||
goto clk_disable;
|
||||
info->clock_speed = clk_get_rate(info->clk) / 1000000;
|
||||
if (info->clock_speed < 10 || info->clock_speed > 48) {
|
||||
ret = -EINVAL;
|
||||
goto clk_disable;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ov7670_init_gpio(client, info);
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/v4l2-mediabus.h>
|
||||
#include <linux/videodev2.h>
|
||||
@@ -414,6 +415,7 @@ struct ov772x_priv {
|
||||
struct v4l2_subdev subdev;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
struct clk *clk;
|
||||
struct regmap *regmap;
|
||||
struct ov772x_camera_info *info;
|
||||
struct gpio_desc *pwdn_gpio;
|
||||
struct gpio_desc *rstb_gpio;
|
||||
@@ -549,51 +551,18 @@ static struct ov772x_priv *to_ov772x(struct v4l2_subdev *sd)
|
||||
return container_of(sd, struct ov772x_priv, subdev);
|
||||
}
|
||||
|
||||
static int ov772x_read(struct i2c_client *client, u8 addr)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
ret = i2c_master_send(client, &addr, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = i2c_master_recv(client, &val, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
|
||||
{
|
||||
return i2c_smbus_write_byte_data(client, addr, value);
|
||||
}
|
||||
|
||||
static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask,
|
||||
u8 set)
|
||||
{
|
||||
s32 val = ov772x_read(client, command);
|
||||
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
val &= ~mask;
|
||||
val |= set & mask;
|
||||
|
||||
return ov772x_write(client, command, val);
|
||||
}
|
||||
|
||||
static int ov772x_reset(struct i2c_client *client)
|
||||
static int ov772x_reset(struct ov772x_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ov772x_write(client, COM7, SCCB_RESET);
|
||||
ret = regmap_write(priv->regmap, COM7, SCCB_RESET);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
usleep_range(1000, 5000);
|
||||
|
||||
return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
|
||||
return regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
|
||||
SOFT_SLEEP_MODE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -611,8 +580,8 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
if (priv->streaming == enable)
|
||||
goto done;
|
||||
|
||||
ret = ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE,
|
||||
enable ? 0 : SOFT_SLEEP_MODE);
|
||||
ret = regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
|
||||
enable ? 0 : SOFT_SLEEP_MODE);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
@@ -657,7 +626,6 @@ static int ov772x_set_frame_rate(struct ov772x_priv *priv,
|
||||
const struct ov772x_color_format *cfmt,
|
||||
const struct ov772x_win_size *win)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
|
||||
unsigned long fin = clk_get_rate(priv->clk);
|
||||
unsigned int best_diff;
|
||||
unsigned int fsize;
|
||||
@@ -723,11 +691,11 @@ static int ov772x_set_frame_rate(struct ov772x_priv *priv,
|
||||
}
|
||||
}
|
||||
|
||||
ret = ov772x_write(client, COM4, com4 | COM4_RESERVED);
|
||||
ret = regmap_write(priv->regmap, COM4, com4 | COM4_RESERVED);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov772x_write(client, CLKRC, clkrc | CLKRC_RESERVED);
|
||||
ret = regmap_write(priv->regmap, CLKRC, clkrc | CLKRC_RESERVED);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -788,8 +756,7 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct ov772x_priv *priv = container_of(ctrl->handler,
|
||||
struct ov772x_priv, hdl);
|
||||
struct v4l2_subdev *sd = &priv->subdev;
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct regmap *regmap = priv->regmap;
|
||||
int ret = 0;
|
||||
u8 val;
|
||||
|
||||
@@ -808,27 +775,27 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
val = ctrl->val ? VFLIP_IMG : 0x00;
|
||||
if (priv->info && (priv->info->flags & OV772X_FLAG_VFLIP))
|
||||
val ^= VFLIP_IMG;
|
||||
return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
|
||||
return regmap_update_bits(regmap, COM3, VFLIP_IMG, val);
|
||||
case V4L2_CID_HFLIP:
|
||||
val = ctrl->val ? HFLIP_IMG : 0x00;
|
||||
if (priv->info && (priv->info->flags & OV772X_FLAG_HFLIP))
|
||||
val ^= HFLIP_IMG;
|
||||
return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
|
||||
return regmap_update_bits(regmap, COM3, HFLIP_IMG, val);
|
||||
case V4L2_CID_BAND_STOP_FILTER:
|
||||
if (!ctrl->val) {
|
||||
/* Switch the filter off, it is on now */
|
||||
ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
|
||||
ret = regmap_update_bits(regmap, BDBASE, 0xff, 0xff);
|
||||
if (!ret)
|
||||
ret = ov772x_mask_set(client, COM8,
|
||||
BNDF_ON_OFF, 0);
|
||||
ret = regmap_update_bits(regmap, COM8,
|
||||
BNDF_ON_OFF, 0);
|
||||
} else {
|
||||
/* Switch the filter on, set AEC low limit */
|
||||
val = 256 - ctrl->val;
|
||||
ret = ov772x_mask_set(client, COM8,
|
||||
BNDF_ON_OFF, BNDF_ON_OFF);
|
||||
ret = regmap_update_bits(regmap, COM8,
|
||||
BNDF_ON_OFF, BNDF_ON_OFF);
|
||||
if (!ret)
|
||||
ret = ov772x_mask_set(client, BDBASE,
|
||||
0xff, val);
|
||||
ret = regmap_update_bits(regmap, BDBASE,
|
||||
0xff, val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -841,18 +808,19 @@ static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
static int ov772x_g_register(struct v4l2_subdev *sd,
|
||||
struct v4l2_dbg_register *reg)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov772x_priv *priv = to_ov772x(sd);
|
||||
int ret;
|
||||
unsigned int val;
|
||||
|
||||
reg->size = 1;
|
||||
if (reg->reg > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ov772x_read(client, reg->reg);
|
||||
ret = regmap_read(priv->regmap, reg->reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
reg->val = (__u64)ret;
|
||||
reg->val = (__u64)val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -860,13 +828,13 @@ static int ov772x_g_register(struct v4l2_subdev *sd,
|
||||
static int ov772x_s_register(struct v4l2_subdev *sd,
|
||||
const struct v4l2_dbg_register *reg)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov772x_priv *priv = to_ov772x(sd);
|
||||
|
||||
if (reg->reg > 0xff ||
|
||||
reg->val > 0xff)
|
||||
return -EINVAL;
|
||||
|
||||
return ov772x_write(client, reg->reg, reg->val);
|
||||
return regmap_write(priv->regmap, reg->reg, reg->val);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -896,6 +864,7 @@ static int ov772x_power_on(struct ov772x_priv *priv)
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(priv->rstb_gpio)) {
|
||||
dev_info(&client->dev, "Unable to get GPIO \"reset\"");
|
||||
clk_disable_unprepare(priv->clk);
|
||||
return PTR_ERR(priv->rstb_gpio);
|
||||
}
|
||||
|
||||
@@ -1004,7 +973,7 @@ static void ov772x_select_params(const struct v4l2_mbus_framefmt *mf,
|
||||
|
||||
static int ov772x_edgectrl(struct ov772x_priv *priv)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
|
||||
struct regmap *regmap = priv->regmap;
|
||||
int ret;
|
||||
|
||||
if (!priv->info)
|
||||
@@ -1018,19 +987,19 @@ static int ov772x_edgectrl(struct ov772x_priv *priv)
|
||||
* Remove it when manual mode.
|
||||
*/
|
||||
|
||||
ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
|
||||
ret = regmap_update_bits(regmap, DSPAUTO, EDGE_ACTRL, 0x00);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov772x_mask_set(client,
|
||||
EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
|
||||
priv->info->edgectrl.threshold);
|
||||
ret = regmap_update_bits(regmap, EDGE_TRSHLD,
|
||||
OV772X_EDGE_THRESHOLD_MASK,
|
||||
priv->info->edgectrl.threshold);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov772x_mask_set(client,
|
||||
EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
|
||||
priv->info->edgectrl.strength);
|
||||
ret = regmap_update_bits(regmap, EDGE_STRNGT,
|
||||
OV772X_EDGE_STRENGTH_MASK,
|
||||
priv->info->edgectrl.strength);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1040,15 +1009,15 @@ static int ov772x_edgectrl(struct ov772x_priv *priv)
|
||||
*
|
||||
* Set upper and lower limit.
|
||||
*/
|
||||
ret = ov772x_mask_set(client,
|
||||
EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
|
||||
priv->info->edgectrl.upper);
|
||||
ret = regmap_update_bits(regmap, EDGE_UPPER,
|
||||
OV772X_EDGE_UPPER_MASK,
|
||||
priv->info->edgectrl.upper);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ov772x_mask_set(client,
|
||||
EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
|
||||
priv->info->edgectrl.lower);
|
||||
ret = regmap_update_bits(regmap, EDGE_LOWER,
|
||||
OV772X_EDGE_LOWER_MASK,
|
||||
priv->info->edgectrl.lower);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -1060,12 +1029,11 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
const struct ov772x_color_format *cfmt,
|
||||
const struct ov772x_win_size *win)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
/* Reset hardware. */
|
||||
ov772x_reset(client);
|
||||
ov772x_reset(priv);
|
||||
|
||||
/* Edge Ctrl. */
|
||||
ret = ov772x_edgectrl(priv);
|
||||
@@ -1073,32 +1041,32 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
return ret;
|
||||
|
||||
/* Format and window size. */
|
||||
ret = ov772x_write(client, HSTART, win->rect.left >> 2);
|
||||
ret = regmap_write(priv->regmap, HSTART, win->rect.left >> 2);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
|
||||
ret = regmap_write(priv->regmap, HSIZE, win->rect.width >> 2);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, VSTART, win->rect.top >> 1);
|
||||
ret = regmap_write(priv->regmap, VSTART, win->rect.top >> 1);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
|
||||
ret = regmap_write(priv->regmap, VSIZE, win->rect.height >> 1);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
|
||||
ret = regmap_write(priv->regmap, HOUTSIZE, win->rect.width >> 2);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
|
||||
ret = regmap_write(priv->regmap, VOUTSIZE, win->rect.height >> 1);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, HREF,
|
||||
ret = regmap_write(priv->regmap, HREF,
|
||||
((win->rect.top & 1) << HREF_VSTART_SHIFT) |
|
||||
((win->rect.left & 3) << HREF_HSTART_SHIFT) |
|
||||
((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
|
||||
((win->rect.width & 3) << HREF_HSIZE_SHIFT));
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
ret = ov772x_write(client, EXHCH,
|
||||
ret = regmap_write(priv->regmap, EXHCH,
|
||||
((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
|
||||
((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
|
||||
if (ret < 0)
|
||||
@@ -1107,15 +1075,14 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
/* Set DSP_CTRL3. */
|
||||
val = cfmt->dsp3;
|
||||
if (val) {
|
||||
ret = ov772x_mask_set(client,
|
||||
DSP_CTRL3, UV_MASK, val);
|
||||
ret = regmap_update_bits(priv->regmap, DSP_CTRL3, UV_MASK, val);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
}
|
||||
|
||||
/* DSP_CTRL4: AEC reference point and DSP output format. */
|
||||
if (cfmt->dsp4) {
|
||||
ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
|
||||
ret = regmap_write(priv->regmap, DSP_CTRL4, cfmt->dsp4);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
}
|
||||
@@ -1131,13 +1098,12 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
if (priv->hflip_ctrl->val)
|
||||
val ^= HFLIP_IMG;
|
||||
|
||||
ret = ov772x_mask_set(client,
|
||||
COM3, SWAP_MASK | IMG_MASK, val);
|
||||
ret = regmap_update_bits(priv->regmap, COM3, SWAP_MASK | IMG_MASK, val);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
|
||||
/* COM7: Sensor resolution and output format control. */
|
||||
ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
|
||||
ret = regmap_write(priv->regmap, COM7, win->com7_bit | cfmt->com7);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
|
||||
@@ -1150,10 +1116,11 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
if (priv->band_filter_ctrl->val) {
|
||||
unsigned short band_filter = priv->band_filter_ctrl->val;
|
||||
|
||||
ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, BNDF_ON_OFF);
|
||||
ret = regmap_update_bits(priv->regmap, COM8,
|
||||
BNDF_ON_OFF, BNDF_ON_OFF);
|
||||
if (!ret)
|
||||
ret = ov772x_mask_set(client, BDBASE,
|
||||
0xff, 256 - band_filter);
|
||||
ret = regmap_update_bits(priv->regmap, BDBASE,
|
||||
0xff, 256 - band_filter);
|
||||
if (ret < 0)
|
||||
goto ov772x_set_fmt_error;
|
||||
}
|
||||
@@ -1162,7 +1129,7 @@ static int ov772x_set_params(struct ov772x_priv *priv,
|
||||
|
||||
ov772x_set_fmt_error:
|
||||
|
||||
ov772x_reset(client);
|
||||
ov772x_reset(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1180,7 +1147,6 @@ static int ov772x_get_selection(struct v4l2_subdev *sd,
|
||||
sel->r.top = 0;
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r.width = priv->win->rect.width;
|
||||
sel->r.height = priv->win->rect.height;
|
||||
@@ -1276,12 +1242,12 @@ static int ov772x_video_probe(struct ov772x_priv *priv)
|
||||
return ret;
|
||||
|
||||
/* Check and show product ID and manufacturer ID. */
|
||||
pid = ov772x_read(client, PID);
|
||||
if (pid < 0)
|
||||
return pid;
|
||||
ver = ov772x_read(client, VER);
|
||||
if (ver < 0)
|
||||
return ver;
|
||||
ret = regmap_read(priv->regmap, PID, &pid);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = regmap_read(priv->regmap, VER, &ver);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (VERSION(pid, ver)) {
|
||||
case OV7720:
|
||||
@@ -1297,12 +1263,12 @@ static int ov772x_video_probe(struct ov772x_priv *priv)
|
||||
goto done;
|
||||
}
|
||||
|
||||
midh = ov772x_read(client, MIDH);
|
||||
if (midh < 0)
|
||||
return midh;
|
||||
midl = ov772x_read(client, MIDL);
|
||||
if (midl < 0)
|
||||
return midl;
|
||||
ret = regmap_read(priv->regmap, MIDH, &midh);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = regmap_read(priv->regmap, MIDL, &midl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_info(&client->dev,
|
||||
"%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
|
||||
@@ -1386,8 +1352,12 @@ static int ov772x_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct ov772x_priv *priv;
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
int ret;
|
||||
static const struct regmap_config ov772x_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = DSPAUTO,
|
||||
};
|
||||
|
||||
if (!client->dev.of_node && !client->dev.platform_data) {
|
||||
dev_err(&client->dev,
|
||||
@@ -1395,16 +1365,16 @@ static int ov772x_probe(struct i2c_client *client,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||
dev_err(&adapter->dev,
|
||||
"I2C-Adapter doesn't support SMBUS_BYTE_DATA\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->regmap = devm_regmap_init_sccb(client, &ov772x_regmap_config);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
dev_err(&client->dev, "Failed to allocate register map\n");
|
||||
return PTR_ERR(priv->regmap);
|
||||
}
|
||||
|
||||
priv->info = client->dev.platform_data;
|
||||
mutex_init(&priv->lock);
|
||||
|
||||
|
@@ -510,7 +510,7 @@ static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
|
||||
int ret;
|
||||
u8 val = 0;
|
||||
|
||||
if (pm_runtime_get_if_in_use(&client->dev) <= 0)
|
||||
if (!pm_runtime_get_if_in_use(&client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <linux/media.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/videodev2.h>
|
||||
@@ -259,7 +260,7 @@ struct ov965x {
|
||||
/* Protects the struct fields below */
|
||||
struct mutex lock;
|
||||
|
||||
struct i2c_client *client;
|
||||
struct regmap *regmap;
|
||||
|
||||
/* Exposure row interval in us */
|
||||
unsigned int exp_row_interval;
|
||||
@@ -424,51 +425,42 @@ static inline struct ov965x *to_ov965x(struct v4l2_subdev *sd)
|
||||
return container_of(sd, struct ov965x, sd);
|
||||
}
|
||||
|
||||
static int ov965x_read(struct i2c_client *client, u8 addr, u8 *val)
|
||||
static int ov965x_read(struct ov965x *ov965x, u8 addr, u8 *val)
|
||||
{
|
||||
u8 buf = addr;
|
||||
struct i2c_msg msg = {
|
||||
.addr = client->addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = &buf
|
||||
};
|
||||
int ret;
|
||||
unsigned int buf;
|
||||
|
||||
ret = i2c_transfer(client->adapter, &msg, 1);
|
||||
if (ret == 1) {
|
||||
msg.flags = I2C_M_RD;
|
||||
ret = i2c_transfer(client->adapter, &msg, 1);
|
||||
ret = regmap_read(ov965x->regmap, addr, &buf);
|
||||
if (!ret)
|
||||
*val = buf;
|
||||
else
|
||||
*val = -1;
|
||||
|
||||
if (ret == 1)
|
||||
*val = buf;
|
||||
}
|
||||
|
||||
v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02x. (%d)\n",
|
||||
v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n",
|
||||
__func__, *val, addr, ret);
|
||||
|
||||
return ret == 1 ? 0 : ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov965x_write(struct i2c_client *client, u8 addr, u8 val)
|
||||
static int ov965x_write(struct ov965x *ov965x, u8 addr, u8 val)
|
||||
{
|
||||
u8 buf[2] = { addr, val };
|
||||
int ret;
|
||||
|
||||
int ret = i2c_master_send(client, buf, 2);
|
||||
ret = regmap_write(ov965x->regmap, addr, val);
|
||||
|
||||
v4l2_dbg(2, debug, client, "%s: 0x%02x @ 0x%02X (%d)\n",
|
||||
v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02X (%d)\n",
|
||||
__func__, val, addr, ret);
|
||||
|
||||
return ret == 2 ? 0 : ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov965x_write_array(struct i2c_client *client,
|
||||
static int ov965x_write_array(struct ov965x *ov965x,
|
||||
const struct i2c_rv *regs)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
|
||||
ret = ov965x_write(client, regs[i].addr, regs[i].value);
|
||||
ret = ov965x_write(ov965x, regs[i].addr, regs[i].value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -486,7 +478,7 @@ static int ov965x_set_default_gamma_curve(struct ov965x *ov965x)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gamma_curve); i++) {
|
||||
int ret = ov965x_write(ov965x->client, addr, gamma_curve[i]);
|
||||
int ret = ov965x_write(ov965x, addr, gamma_curve[i]);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -506,7 +498,7 @@ static int ov965x_set_color_matrix(struct ov965x *ov965x)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mtx); i++) {
|
||||
int ret = ov965x_write(ov965x->client, addr, mtx[i]);
|
||||
int ret = ov965x_write(ov965x, addr, mtx[i]);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -542,16 +534,15 @@ static int __ov965x_set_power(struct ov965x *ov965x, int on)
|
||||
static int ov965x_s_power(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
struct ov965x *ov965x = to_ov965x(sd);
|
||||
struct i2c_client *client = ov965x->client;
|
||||
int ret = 0;
|
||||
|
||||
v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on);
|
||||
v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
|
||||
|
||||
mutex_lock(&ov965x->lock);
|
||||
if (ov965x->power == !on) {
|
||||
ret = __ov965x_set_power(ov965x, on);
|
||||
if (!ret && on) {
|
||||
ret = ov965x_write_array(client,
|
||||
ret = ov965x_write_array(ov965x,
|
||||
ov965x_init_regs);
|
||||
ov965x->apply_frame_fmt = 1;
|
||||
ov965x->ctrls.update = 1;
|
||||
@@ -609,13 +600,13 @@ static int ov965x_set_banding_filter(struct ov965x *ov965x, int value)
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
ret = ov965x_read(ov965x->client, REG_COM8, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM8, ®);
|
||||
if (!ret) {
|
||||
if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED)
|
||||
reg &= ~COM8_BFILT;
|
||||
else
|
||||
reg |= COM8_BFILT;
|
||||
ret = ov965x_write(ov965x->client, REG_COM8, reg);
|
||||
ret = ov965x_write(ov965x, REG_COM8, reg);
|
||||
}
|
||||
if (value == V4L2_CID_POWER_LINE_FREQUENCY_DISABLED)
|
||||
return 0;
|
||||
@@ -631,7 +622,7 @@ static int ov965x_set_banding_filter(struct ov965x *ov965x, int value)
|
||||
ov965x->fiv->interval.numerator;
|
||||
mbd = ((mbd / (light_freq * 2)) + 500) / 1000UL;
|
||||
|
||||
return ov965x_write(ov965x->client, REG_MBD, mbd);
|
||||
return ov965x_write(ov965x, REG_MBD, mbd);
|
||||
}
|
||||
|
||||
static int ov965x_set_white_balance(struct ov965x *ov965x, int awb)
|
||||
@@ -639,17 +630,17 @@ static int ov965x_set_white_balance(struct ov965x *ov965x, int awb)
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
ret = ov965x_read(ov965x->client, REG_COM8, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM8, ®);
|
||||
if (!ret) {
|
||||
reg = awb ? reg | REG_COM8 : reg & ~REG_COM8;
|
||||
ret = ov965x_write(ov965x->client, REG_COM8, reg);
|
||||
ret = ov965x_write(ov965x, REG_COM8, reg);
|
||||
}
|
||||
if (!ret && !awb) {
|
||||
ret = ov965x_write(ov965x->client, REG_BLUE,
|
||||
ret = ov965x_write(ov965x, REG_BLUE,
|
||||
ov965x->ctrls.blue_balance->val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_write(ov965x->client, REG_RED,
|
||||
ret = ov965x_write(ov965x, REG_RED,
|
||||
ov965x->ctrls.red_balance->val);
|
||||
}
|
||||
return ret;
|
||||
@@ -677,14 +668,13 @@ static int ov965x_set_brightness(struct ov965x *ov965x, int val)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < NUM_BR_REGS && !ret; i++)
|
||||
ret = ov965x_write(ov965x->client, regs[0][i],
|
||||
ret = ov965x_write(ov965x, regs[0][i],
|
||||
regs[val][i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
|
||||
{
|
||||
struct i2c_client *client = ov965x->client;
|
||||
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
|
||||
int ret = 0;
|
||||
u8 reg;
|
||||
@@ -693,14 +683,14 @@ static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
|
||||
* gain value in REG_VREF, REG_GAIN is not overwritten.
|
||||
*/
|
||||
if (ctrls->auto_gain->is_new) {
|
||||
ret = ov965x_read(client, REG_COM8, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM8, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ctrls->auto_gain->val)
|
||||
reg |= COM8_AGC;
|
||||
else
|
||||
reg &= ~COM8_AGC;
|
||||
ret = ov965x_write(client, REG_COM8, reg);
|
||||
ret = ov965x_write(ov965x, REG_COM8, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -719,15 +709,15 @@ static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
|
||||
rgain = (gain - ((1 << m) * 16)) / (1 << m);
|
||||
rgain |= (((1 << m) - 1) << 4);
|
||||
|
||||
ret = ov965x_write(client, REG_GAIN, rgain & 0xff);
|
||||
ret = ov965x_write(ov965x, REG_GAIN, rgain & 0xff);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(client, REG_VREF, ®);
|
||||
ret = ov965x_read(ov965x, REG_VREF, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
reg &= ~VREF_GAIN_MASK;
|
||||
reg |= (((rgain >> 8) & 0x3) << 6);
|
||||
ret = ov965x_write(client, REG_VREF, reg);
|
||||
ret = ov965x_write(ov965x, REG_VREF, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Return updated control's value to userspace */
|
||||
@@ -742,10 +732,10 @@ static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value)
|
||||
u8 com14, edge;
|
||||
int ret;
|
||||
|
||||
ret = ov965x_read(ov965x->client, REG_COM14, &com14);
|
||||
ret = ov965x_read(ov965x, REG_COM14, &com14);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(ov965x->client, REG_EDGE, &edge);
|
||||
ret = ov965x_read(ov965x, REG_EDGE, &edge);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
com14 = value ? com14 | COM14_EDGE_EN : com14 & ~COM14_EDGE_EN;
|
||||
@@ -756,33 +746,32 @@ static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value)
|
||||
} else {
|
||||
com14 &= ~COM14_EEF_X2;
|
||||
}
|
||||
ret = ov965x_write(ov965x->client, REG_COM14, com14);
|
||||
ret = ov965x_write(ov965x, REG_COM14, com14);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
edge &= ~EDGE_FACTOR_MASK;
|
||||
edge |= ((u8)value & 0x0f);
|
||||
|
||||
return ov965x_write(ov965x->client, REG_EDGE, edge);
|
||||
return ov965x_write(ov965x, REG_EDGE, edge);
|
||||
}
|
||||
|
||||
static int ov965x_set_exposure(struct ov965x *ov965x, int exp)
|
||||
{
|
||||
struct i2c_client *client = ov965x->client;
|
||||
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
|
||||
bool auto_exposure = (exp == V4L2_EXPOSURE_AUTO);
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
if (ctrls->auto_exp->is_new) {
|
||||
ret = ov965x_read(client, REG_COM8, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM8, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (auto_exposure)
|
||||
reg |= (COM8_AEC | COM8_AGC);
|
||||
else
|
||||
reg &= ~(COM8_AEC | COM8_AGC);
|
||||
ret = ov965x_write(client, REG_COM8, reg);
|
||||
ret = ov965x_write(ov965x, REG_COM8, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -794,12 +783,12 @@ static int ov965x_set_exposure(struct ov965x *ov965x, int exp)
|
||||
* Manual exposure value
|
||||
* [b15:b0] - AECHM (b15:b10), AECH (b9:b2), COM1 (b1:b0)
|
||||
*/
|
||||
ret = ov965x_write(client, REG_COM1, exposure & 0x3);
|
||||
ret = ov965x_write(ov965x, REG_COM1, exposure & 0x3);
|
||||
if (!ret)
|
||||
ret = ov965x_write(client, REG_AECH,
|
||||
ret = ov965x_write(ov965x, REG_AECH,
|
||||
(exposure >> 2) & 0xff);
|
||||
if (!ret)
|
||||
ret = ov965x_write(client, REG_AECHM,
|
||||
ret = ov965x_write(ov965x, REG_AECHM,
|
||||
(exposure >> 10) & 0x3f);
|
||||
/* Update the value to minimize rounding errors */
|
||||
ctrls->exposure->val = ((exposure * ov965x->exp_row_interval)
|
||||
@@ -822,7 +811,7 @@ static int ov965x_set_flip(struct ov965x *ov965x)
|
||||
if (ov965x->ctrls.vflip->val)
|
||||
mvfp |= MVFP_FLIP;
|
||||
|
||||
return ov965x_write(ov965x->client, REG_MVFP, mvfp);
|
||||
return ov965x_write(ov965x, REG_MVFP, mvfp);
|
||||
}
|
||||
|
||||
#define NUM_SAT_LEVELS 5
|
||||
@@ -846,7 +835,7 @@ static int ov965x_set_saturation(struct ov965x *ov965x, int val)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < NUM_SAT_REGS && !ret; i++)
|
||||
ret = ov965x_write(ov965x->client, addr + i, regs[val][i]);
|
||||
ret = ov965x_write(ov965x, addr + i, regs[val][i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -856,16 +845,15 @@ static int ov965x_set_test_pattern(struct ov965x *ov965x, int value)
|
||||
int ret;
|
||||
u8 reg;
|
||||
|
||||
ret = ov965x_read(ov965x->client, REG_COM23, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM23, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
reg = value ? reg | COM23_TEST_MODE : reg & ~COM23_TEST_MODE;
|
||||
return ov965x_write(ov965x->client, REG_COM23, reg);
|
||||
return ov965x_write(ov965x, REG_COM23, reg);
|
||||
}
|
||||
|
||||
static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct i2c_client *client = ov965x->client;
|
||||
unsigned int exposure, gain, m;
|
||||
u8 reg0, reg1, reg2;
|
||||
int ret;
|
||||
@@ -877,10 +865,10 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
if (!ctrl->val)
|
||||
return 0;
|
||||
ret = ov965x_read(client, REG_GAIN, ®0);
|
||||
ret = ov965x_read(ov965x, REG_GAIN, ®0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(client, REG_VREF, ®1);
|
||||
ret = ov965x_read(ov965x, REG_VREF, ®1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
gain = ((reg1 >> 6) << 8) | reg0;
|
||||
@@ -891,13 +879,13 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
|
||||
case V4L2_CID_EXPOSURE_AUTO:
|
||||
if (ctrl->val == V4L2_EXPOSURE_MANUAL)
|
||||
return 0;
|
||||
ret = ov965x_read(client, REG_COM1, ®0);
|
||||
ret = ov965x_read(ov965x, REG_COM1, ®0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(client, REG_AECH, ®1);
|
||||
ret = ov965x_read(ov965x, REG_AECH, ®1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(client, REG_AECHM, ®2);
|
||||
ret = ov965x_read(ov965x, REG_AECHM, ®2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
exposure = ((reg2 & 0x3f) << 10) | (reg1 << 2) |
|
||||
@@ -1279,32 +1267,31 @@ static int ov965x_set_frame_size(struct ov965x *ov965x)
|
||||
int i, ret = 0;
|
||||
|
||||
for (i = 0; ret == 0 && i < NUM_FMT_REGS; i++)
|
||||
ret = ov965x_write(ov965x->client, frame_size_reg_addr[i],
|
||||
ret = ov965x_write(ov965x, frame_size_reg_addr[i],
|
||||
ov965x->frame_size->regs[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __ov965x_set_params(struct ov965x *ov965x)
|
||||
{
|
||||
struct i2c_client *client = ov965x->client;
|
||||
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
|
||||
int ret = 0;
|
||||
u8 reg;
|
||||
|
||||
if (ov965x->apply_frame_fmt) {
|
||||
reg = DEF_CLKRC + ov965x->fiv->clkrc_div;
|
||||
ret = ov965x_write(client, REG_CLKRC, reg);
|
||||
ret = ov965x_write(ov965x, REG_CLKRC, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_set_frame_size(ov965x);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = ov965x_read(client, REG_TSLB, ®);
|
||||
ret = ov965x_read(ov965x, REG_TSLB, ®);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
reg &= ~TSLB_YUYV_MASK;
|
||||
reg |= ov965x->tslb_reg;
|
||||
ret = ov965x_write(client, REG_TSLB, reg);
|
||||
ret = ov965x_write(ov965x, REG_TSLB, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -1318,10 +1305,10 @@ static int __ov965x_set_params(struct ov965x *ov965x)
|
||||
* Select manual banding filter, the filter will
|
||||
* be enabled further if required.
|
||||
*/
|
||||
ret = ov965x_read(client, REG_COM11, ®);
|
||||
ret = ov965x_read(ov965x, REG_COM11, ®);
|
||||
if (!ret)
|
||||
reg |= COM11_BANDING;
|
||||
ret = ov965x_write(client, REG_COM11, reg);
|
||||
ret = ov965x_write(ov965x, REG_COM11, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/*
|
||||
@@ -1333,12 +1320,11 @@ static int __ov965x_set_params(struct ov965x *ov965x)
|
||||
|
||||
static int ov965x_s_stream(struct v4l2_subdev *sd, int on)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov965x *ov965x = to_ov965x(sd);
|
||||
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
|
||||
int ret = 0;
|
||||
|
||||
v4l2_dbg(1, debug, client, "%s: on: %d\n", __func__, on);
|
||||
v4l2_dbg(1, debug, sd, "%s: on: %d\n", __func__, on);
|
||||
|
||||
mutex_lock(&ov965x->lock);
|
||||
if (ov965x->streaming == !on) {
|
||||
@@ -1358,7 +1344,7 @@ static int ov965x_s_stream(struct v4l2_subdev *sd, int on)
|
||||
ctrls->update = 0;
|
||||
}
|
||||
if (!ret)
|
||||
ret = ov965x_write(client, REG_COM2,
|
||||
ret = ov965x_write(ov965x, REG_COM2,
|
||||
on ? 0x01 : 0x11);
|
||||
}
|
||||
if (!ret)
|
||||
@@ -1421,6 +1407,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
|
||||
{
|
||||
int ret, i;
|
||||
int gpios[NUM_GPIOS];
|
||||
struct device *dev = regmap_get_device(ov965x->regmap);
|
||||
|
||||
gpios[GPIO_PWDN] = pdata->gpio_pwdn;
|
||||
gpios[GPIO_RST] = pdata->gpio_reset;
|
||||
@@ -1430,7 +1417,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
|
||||
|
||||
if (!gpio_is_valid(gpio))
|
||||
continue;
|
||||
ret = devm_gpio_request_one(&ov965x->client->dev, gpio,
|
||||
ret = devm_gpio_request_one(dev, gpio,
|
||||
GPIOF_OUT_INIT_HIGH, "OV965X");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -1446,7 +1433,7 @@ static int ov965x_configure_gpios_pdata(struct ov965x *ov965x,
|
||||
|
||||
static int ov965x_configure_gpios(struct ov965x *ov965x)
|
||||
{
|
||||
struct device *dev = &ov965x->client->dev;
|
||||
struct device *dev = regmap_get_device(ov965x->regmap);
|
||||
|
||||
ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown",
|
||||
GPIOD_OUT_HIGH);
|
||||
@@ -1467,7 +1454,6 @@ static int ov965x_configure_gpios(struct ov965x *ov965x)
|
||||
|
||||
static int ov965x_detect_sensor(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct ov965x *ov965x = to_ov965x(sd);
|
||||
u8 pid, ver;
|
||||
int ret;
|
||||
@@ -1480,9 +1466,9 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd)
|
||||
msleep(25);
|
||||
|
||||
/* Check sensor revision */
|
||||
ret = ov965x_read(client, REG_PID, &pid);
|
||||
ret = ov965x_read(ov965x, REG_PID, &pid);
|
||||
if (!ret)
|
||||
ret = ov965x_read(client, REG_VER, &ver);
|
||||
ret = ov965x_read(ov965x, REG_VER, &ver);
|
||||
|
||||
__ov965x_set_power(ov965x, 0);
|
||||
|
||||
@@ -1509,12 +1495,21 @@ static int ov965x_probe(struct i2c_client *client,
|
||||
struct v4l2_subdev *sd;
|
||||
struct ov965x *ov965x;
|
||||
int ret;
|
||||
static const struct regmap_config ov965x_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xab,
|
||||
};
|
||||
|
||||
ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL);
|
||||
if (!ov965x)
|
||||
return -ENOMEM;
|
||||
|
||||
ov965x->client = client;
|
||||
ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config);
|
||||
if (IS_ERR(ov965x->regmap)) {
|
||||
dev_err(&client->dev, "Failed to allocate register map\n");
|
||||
return PTR_ERR(ov965x->regmap);
|
||||
}
|
||||
|
||||
if (pdata) {
|
||||
if (pdata->mclk_frequency == 0) {
|
||||
@@ -1527,7 +1522,7 @@ static int ov965x_probe(struct i2c_client *client,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (dev_fwnode(&client->dev)) {
|
||||
ov965x->clk = devm_clk_get(&ov965x->client->dev, NULL);
|
||||
ov965x->clk = devm_clk_get(&client->dev, NULL);
|
||||
if (IS_ERR(ov965x->clk))
|
||||
return PTR_ERR(ov965x->clk);
|
||||
ov965x->mclk_frequency = clk_get_rate(ov965x->clk);
|
||||
@@ -1546,7 +1541,7 @@ static int ov965x_probe(struct i2c_client *client,
|
||||
|
||||
sd = &ov965x->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &ov965x_subdev_ops);
|
||||
strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
|
||||
strscpy(sd->name, DRIVER_NAME, sizeof(sd->name));
|
||||
|
||||
sd->internal_ops = &ov965x_sd_internal_ops;
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
|
||||
|
@@ -589,7 +589,6 @@ static int rj54n1_get_selection(struct v4l2_subdev *sd,
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
sel->r.left = RJ54N1_COLUMN_SKIP;
|
||||
sel->r.top = RJ54N1_ROW_SKIP;
|
||||
sel->r.width = RJ54N1_MAX_WIDTH;
|
||||
|
@@ -1603,7 +1603,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
|
||||
const struct s5c73m3_platform_data *pdata = dev->platform_data;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct device_node *node_ep;
|
||||
struct v4l2_fwnode_endpoint ep;
|
||||
struct v4l2_fwnode_endpoint ep = { .bus_type = 0 };
|
||||
int ret;
|
||||
|
||||
if (!node) {
|
||||
@@ -1644,7 +1644,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ep.bus_type != V4L2_MBUS_CSI2) {
|
||||
if (ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
|
||||
dev_err(dev, "unsupported bus type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1683,7 +1683,7 @@ static int s5c73m3_probe(struct i2c_client *client,
|
||||
v4l2_subdev_init(sd, &s5c73m3_subdev_ops);
|
||||
sd->owner = client->dev.driver->owner;
|
||||
v4l2_set_subdevdata(sd, state);
|
||||
strlcpy(sd->name, "S5C73M3", sizeof(sd->name));
|
||||
strscpy(sd->name, "S5C73M3", sizeof(sd->name));
|
||||
|
||||
sd->internal_ops = &s5c73m3_internal_ops;
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
@@ -1698,7 +1698,8 @@ static int s5c73m3_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
|
||||
v4l2_i2c_subdev_init(oif_sd, client, &oif_subdev_ops);
|
||||
strcpy(oif_sd->name, "S5C73M3-OIF");
|
||||
/* Static name; NEVER use in new drivers! */
|
||||
strscpy(oif_sd->name, "S5C73M3-OIF", sizeof(oif_sd->name));
|
||||
|
||||
oif_sd->internal_ops = &oif_internal_ops;
|
||||
oif_sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
@@ -954,7 +954,8 @@ static int s5k4ecgx_probe(struct i2c_client *client,
|
||||
sd = &priv->sd;
|
||||
/* Registering subdev */
|
||||
v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
|
||||
strlcpy(sd->name, S5K4ECGX_DRIVER_NAME, sizeof(sd->name));
|
||||
/* Static name; NEVER use in new drivers! */
|
||||
strscpy(sd->name, S5K4ECGX_DRIVER_NAME, sizeof(sd->name));
|
||||
|
||||
sd->internal_ops = &s5k4ecgx_subdev_internal_ops;
|
||||
/* Support v4l2 sub-device user space API */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user