mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge tag 'media/v6.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull missed media updates from Mauro Carvalho Chehab:
"It seems I screwed-up my previous pull request: it ends up that only
half of the media patches that were in linux-next got merged in -rc1.
The script which creates the signed tags silently failed due to
5.19->6.0 so it ended generating a tag with incomplete stuff.
So here are the missing parts:
- a DVB core security fix
- lots of fixes and cleanups for atomisp staging driver
- old drivers that are VB1 are being moved to staging to be
deprecated
- several driver updates - mostly for embedded systems, but there are
also some things addressing issues with some PC webcams, in the UVC
video driver"
* tag 'media/v6.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (163 commits)
media: sun6i-csi: Move csi buffer definition to main header file
media: sun6i-csi: Introduce and use video helper functions
media: sun6i-csi: Add media ops with link notify callback
media: sun6i-csi: Remove controls handler from the driver
media: sun6i-csi: Register the media device after creation
media: sun6i-csi: Pass and store csi device directly in video code
media: sun6i-csi: Tidy up video code
media: sun6i-csi: Tidy up v4l2 code
media: sun6i-csi: Tidy up Kconfig
media: sun6i-csi: Use runtime pm for clocks and reset
media: sun6i-csi: Define and use variant to get module clock rate
media: sun6i-csi: Always set exclusive module clock rate
media: sun6i-csi: Tidy up platform code
media: sun6i-csi: Refactor main driver data structures
media: sun6i-csi: Define and use driver name and (reworked) description
media: cedrus: Add a Kconfig dependency on RESET_CONTROLLER
media: sun8i-rotate: Add a Kconfig dependency on RESET_CONTROLLER
media: sun8i-di: Add a Kconfig dependency on RESET_CONTROLLER
media: sun4i-csi: Add a Kconfig dependency on RESET_CONTROLLER
media: sun6i-csi: Add a Kconfig dependency on RESET_CONTROLLER
...
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
Dongwoon Anatech DW9714 camera voice coil lens driver
|
||||
|
||||
DW9174 is a 10-bit DAC with current sink capability. It is intended
|
||||
for driving voice coil lenses in camera modules.
|
||||
|
||||
Mandatory properties:
|
||||
|
||||
- compatible: "dongwoon,dw9714"
|
||||
- reg: I²C slave address
|
||||
@@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/media/i2c/dongwoon,dw9714.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Dongwoon Anatech DW9714 camera voice coil lens driver
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
||||
description:
|
||||
DW9174 is a 10-bit DAC with current sink capability. It is intended for
|
||||
driving voice coil lenses in camera modules.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: dongwoon,dw9714
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
powerdown-gpios:
|
||||
description:
|
||||
XSD pin for shutdown (active low)
|
||||
|
||||
vcc-supply:
|
||||
description: VDD power supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
camera-lens@c {
|
||||
compatible = "dongwoon,dw9714";
|
||||
reg = <0x0c>;
|
||||
vcc-supply = <®_csi_1v8>;
|
||||
};
|
||||
};
|
||||
@@ -214,18 +214,29 @@ Link properties can be modified at runtime by calling
|
||||
Pipelines and media streams
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A media stream is a stream of pixels or metadata originating from one or more
|
||||
source devices (such as a sensors) and flowing through media entity pads
|
||||
towards the final sinks. The stream can be modified on the route by the
|
||||
devices (e.g. scaling or pixel format conversions), or it can be split into
|
||||
multiple branches, or multiple branches can be merged.
|
||||
|
||||
A media pipeline is a set of media streams which are interdependent. This
|
||||
interdependency can be caused by the hardware (e.g. configuration of a second
|
||||
stream cannot be changed if the first stream has been enabled) or by the driver
|
||||
due to the software design. Most commonly a media pipeline consists of a single
|
||||
stream which does not branch.
|
||||
|
||||
When starting streaming, drivers must notify all entities in the pipeline to
|
||||
prevent link states from being modified during streaming by calling
|
||||
:c:func:`media_pipeline_start()`.
|
||||
|
||||
The function will mark all entities connected to the given entity through
|
||||
enabled links, either directly or indirectly, as streaming.
|
||||
The function will mark all the pads which are part of the pipeline as streaming.
|
||||
|
||||
The struct media_pipeline instance pointed to by
|
||||
the pipe argument will be stored in every entity in the pipeline.
|
||||
the pipe argument will be stored in every pad in the pipeline.
|
||||
Drivers should embed the struct media_pipeline
|
||||
in higher-level pipeline structures and can then access the
|
||||
pipeline through the struct media_entity
|
||||
pipeline through the struct media_pad
|
||||
pipe field.
|
||||
|
||||
Calls to :c:func:`media_pipeline_start()` can be nested.
|
||||
|
||||
@@ -239,6 +239,7 @@ ignore define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL
|
||||
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE
|
||||
ignore define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX
|
||||
ignore define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX
|
||||
ignore define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_VOLUME_LEVEL
|
||||
|
||||
ignore define CEC_MSG_GIVE_FEATURES
|
||||
|
||||
@@ -487,6 +488,7 @@ ignore define CEC_OP_SYS_AUD_STATUS_ON
|
||||
|
||||
ignore define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST
|
||||
ignore define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS
|
||||
ignore define CEC_MSG_SET_AUDIO_VOLUME_LEVEL
|
||||
|
||||
ignore define CEC_OP_AUD_FMT_ID_CEA861
|
||||
ignore define CEC_OP_AUD_FMT_ID_CEA861_CXT
|
||||
|
||||
@@ -136,9 +136,9 @@ V4L2 functions
|
||||
|
||||
operates like the :c:func:`read()` function.
|
||||
|
||||
.. c:function:: void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
|
||||
.. c:function:: void *v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset);
|
||||
|
||||
operates like the :c:func:`munmap()` function.
|
||||
operates like the :c:func:`mmap()` function.
|
||||
|
||||
.. c:function:: int v4l2_munmap(void *_start, size_t length);
|
||||
|
||||
|
||||
@@ -6284,7 +6284,7 @@ M: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt
|
||||
F: Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.yaml
|
||||
F: drivers/media/i2c/dw9714.c
|
||||
|
||||
DONGWOON DW9768 LENS VOICE COIL DRIVER
|
||||
@@ -18141,7 +18141,6 @@ L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
F: drivers/staging/media/deprecated/saa7146/
|
||||
F: include/media/drv-intf/saa7146*
|
||||
|
||||
SAFESETID SECURITY MODULE
|
||||
M: Micah Morton <mortonm@chromium.org>
|
||||
@@ -22771,7 +22770,7 @@ S: Maintained
|
||||
W: http://mjpeg.sourceforge.net/driver-zoran/
|
||||
Q: https://patchwork.linuxtv.org/project/linux-media/list/
|
||||
F: Documentation/driver-api/media/drivers/zoran.rst
|
||||
F: drivers/staging/media/zoran/
|
||||
F: drivers/media/pci/zoran/
|
||||
|
||||
ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
|
||||
M: Minchan Kim <minchan@kernel.org>
|
||||
|
||||
@@ -24,7 +24,7 @@ if MEDIA_SUPPORT
|
||||
|
||||
config MEDIA_SUPPORT_FILTER
|
||||
bool "Filter media drivers"
|
||||
default y if !EMBEDDED && !EXPERT
|
||||
default y if !EXPERT
|
||||
help
|
||||
Configuring the media subsystem can be complex, as there are
|
||||
hundreds of drivers and other config options.
|
||||
|
||||
@@ -1027,6 +1027,7 @@ static const u8 cec_msg_size[256] = {
|
||||
[CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
|
||||
[CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR] = 2 | DIRECTED,
|
||||
[CEC_MSG_SET_SYSTEM_AUDIO_MODE] = 3 | BOTH,
|
||||
[CEC_MSG_SET_AUDIO_VOLUME_LEVEL] = 3 | DIRECTED,
|
||||
[CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST] = 2 | DIRECTED,
|
||||
[CEC_MSG_SYSTEM_AUDIO_MODE_STATUS] = 3 | DIRECTED,
|
||||
[CEC_MSG_SET_AUDIO_RATE] = 3 | DIRECTED,
|
||||
|
||||
@@ -44,6 +44,8 @@ static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
|
||||
uint8_t *cec_message = cros_ec->event_data.data.cec_message;
|
||||
unsigned int len = cros_ec->event_size;
|
||||
|
||||
if (len > CEC_MAX_MSG_SIZE)
|
||||
len = CEC_MAX_MSG_SIZE;
|
||||
cros_ec_cec->rx_msg.len = len;
|
||||
memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
|
||||
|
||||
@@ -221,6 +223,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
|
||||
{ "Google", "Moli", "0000:00:02.0", "Port B" },
|
||||
/* Google Kinox */
|
||||
{ "Google", "Kinox", "0000:00:02.0", "Port B" },
|
||||
/* Google Kuldax */
|
||||
{ "Google", "Kuldax", "0000:00:02.0", "Port B" },
|
||||
};
|
||||
|
||||
static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
|
||||
|
||||
@@ -115,6 +115,8 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
|
||||
dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
|
||||
cec->rx = STATE_BUSY;
|
||||
cec->msg.len = status >> 24;
|
||||
if (cec->msg.len > CEC_MAX_MSG_SIZE)
|
||||
cec->msg.len = CEC_MAX_MSG_SIZE;
|
||||
cec->msg.rx_status = CEC_RX_STATUS_OK;
|
||||
s5p_cec_get_rx_buf(cec, cec->msg.len,
|
||||
cec->msg.msg);
|
||||
|
||||
@@ -6660,7 +6660,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
u16 err;
|
||||
u16 err = 0;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
|
||||
@@ -406,7 +406,6 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_format *format)
|
||||
{
|
||||
struct ar0521_dev *sensor = to_ar0521_dev(sd);
|
||||
int ret = 0;
|
||||
|
||||
ar0521_adj_fmt(&format->format);
|
||||
|
||||
@@ -423,7 +422,7 @@ static int ar0521_set_fmt(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
mutex_unlock(&sensor->lock);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar0521_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
@@ -756,10 +755,12 @@ static int ar0521_power_on(struct device *dev)
|
||||
gpiod_set_value(sensor->reset_gpio, 0);
|
||||
usleep_range(4500, 5000); /* min 45000 clocks */
|
||||
|
||||
for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++)
|
||||
if (ar0521_write_regs(sensor, initial_regs[cnt].data,
|
||||
initial_regs[cnt].count))
|
||||
for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) {
|
||||
ret = ar0521_write_regs(sensor, initial_regs[cnt].data,
|
||||
initial_regs[cnt].count);
|
||||
if (ret)
|
||||
goto off;
|
||||
}
|
||||
|
||||
ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT,
|
||||
AR0521_REG_SERIAL_FORMAT_MIPI |
|
||||
|
||||
@@ -238,6 +238,43 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int get_key_geniatech(struct IR_i2c *ir, enum rc_proto *protocol,
|
||||
u32 *scancode, u8 *toggle)
|
||||
{
|
||||
int i, rc;
|
||||
unsigned char b;
|
||||
|
||||
/* poll IR chip */
|
||||
for (i = 0; i < 4; i++) {
|
||||
rc = i2c_master_recv(ir->c, &b, 1);
|
||||
if (rc == 1)
|
||||
break;
|
||||
msleep(20);
|
||||
}
|
||||
if (rc != 1) {
|
||||
dev_dbg(&ir->rc->dev, "read error\n");
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* don't repeat the key */
|
||||
if (ir->old == b)
|
||||
return 0;
|
||||
ir->old = b;
|
||||
|
||||
/* decode to RC5 */
|
||||
b &= 0x7f;
|
||||
b = (b - 1) / 2;
|
||||
|
||||
dev_dbg(&ir->rc->dev, "key %02x\n", b);
|
||||
|
||||
*protocol = RC_PROTO_RC5;
|
||||
*scancode = b;
|
||||
*toggle = ir->old >> 7;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
|
||||
u32 *scancode, u8 *toggle)
|
||||
{
|
||||
@@ -766,6 +803,13 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
rc_proto = RC_PROTO_BIT_OTHER;
|
||||
ir_codes = RC_MAP_EMPTY;
|
||||
break;
|
||||
case 0x33:
|
||||
name = "Geniatech";
|
||||
ir->get_key = get_key_geniatech;
|
||||
rc_proto = RC_PROTO_BIT_RC5;
|
||||
ir_codes = RC_MAP_TOTAL_MEDIA_IN_HAND_02;
|
||||
ir->old = 0xfc;
|
||||
break;
|
||||
case 0x6b:
|
||||
name = "FusionHDTV";
|
||||
ir->get_key = get_key_fusionhdtv;
|
||||
@@ -825,6 +869,9 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
case IR_KBD_GET_KEY_KNC1:
|
||||
ir->get_key = get_key_knc1;
|
||||
break;
|
||||
case IR_KBD_GET_KEY_GENIATECH:
|
||||
ir->get_key = get_key_geniatech;
|
||||
break;
|
||||
case IR_KBD_GET_KEY_FUSIONHDTV:
|
||||
ir->get_key = get_key_fusionhdtv;
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_graph.h>
|
||||
|
||||
@@ -633,7 +633,7 @@ static int mt9v111_hw_config(struct mt9v111_dev *mt9v111)
|
||||
|
||||
/*
|
||||
* Set pixel integration time to the whole frame time.
|
||||
* This value controls the the shutter delay when running with AE
|
||||
* This value controls the shutter delay when running with AE
|
||||
* disabled. If longer than frame time, it affects the output
|
||||
* frame rate.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
@@ -447,8 +448,6 @@ struct ov5640_dev {
|
||||
/* lock to protect all members below */
|
||||
struct mutex lock;
|
||||
|
||||
int power_count;
|
||||
|
||||
struct v4l2_mbus_framefmt fmt;
|
||||
bool pending_fmt_change;
|
||||
|
||||
@@ -2696,39 +2695,24 @@ power_off:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* --------------- Subdev Operations --------------- */
|
||||
|
||||
static int ov5640_s_power(struct v4l2_subdev *sd, int on)
|
||||
static int ov5640_sensor_suspend(struct device *dev)
|
||||
{
|
||||
struct ov5640_dev *sensor = to_ov5640_dev(sd);
|
||||
int ret = 0;
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov5640_dev *ov5640 = to_ov5640_dev(sd);
|
||||
|
||||
mutex_lock(&sensor->lock);
|
||||
|
||||
/*
|
||||
* If the power count is modified from 0 to != 0 or from != 0 to 0,
|
||||
* update the power state.
|
||||
*/
|
||||
if (sensor->power_count == !on) {
|
||||
ret = ov5640_set_power(sensor, !!on);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update the power count. */
|
||||
sensor->power_count += on ? 1 : -1;
|
||||
WARN_ON(sensor->power_count < 0);
|
||||
out:
|
||||
mutex_unlock(&sensor->lock);
|
||||
|
||||
if (on && !ret && sensor->power_count == 1) {
|
||||
/* restore controls */
|
||||
ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ov5640_set_power(ov5640, false);
|
||||
}
|
||||
|
||||
static int ov5640_sensor_resume(struct device *dev)
|
||||
{
|
||||
struct v4l2_subdev *sd = dev_get_drvdata(dev);
|
||||
struct ov5640_dev *ov5640 = to_ov5640_dev(sd);
|
||||
|
||||
return ov5640_set_power(ov5640, true);
|
||||
}
|
||||
|
||||
/* --------------- Subdev Operations --------------- */
|
||||
|
||||
static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
|
||||
struct v4l2_fract *fi,
|
||||
u32 width, u32 height)
|
||||
@@ -3314,6 +3298,9 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
|
||||
/* v4l2_ctrl_lock() locks our own mutex */
|
||||
|
||||
if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
val = ov5640_get_gain(sensor);
|
||||
@@ -3329,6 +3316,8 @@ static int ov5640_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3358,9 +3347,9 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
/*
|
||||
* If the device is not powered up by the host driver do
|
||||
* not apply any controls to H/W at this time. Instead
|
||||
* the controls will be restored right after power-up.
|
||||
* the controls will be restored at start streaming time.
|
||||
*/
|
||||
if (sensor->power_count == 0)
|
||||
if (!pm_runtime_get_if_in_use(&sensor->i2c_client->dev))
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
@@ -3402,6 +3391,8 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
break;
|
||||
}
|
||||
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3677,6 +3668,18 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
struct ov5640_dev *sensor = to_ov5640_dev(sd);
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
ret = pm_runtime_resume_and_get(&sensor->i2c_client->dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
|
||||
if (ret) {
|
||||
pm_runtime_put(&sensor->i2c_client->dev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&sensor->lock);
|
||||
|
||||
if (sensor->streaming == !enable) {
|
||||
@@ -3701,8 +3704,13 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
|
||||
if (!ret)
|
||||
sensor->streaming = enable;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&sensor->lock);
|
||||
|
||||
if (!enable || ret)
|
||||
pm_runtime_put_autosuspend(&sensor->i2c_client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3724,7 +3732,6 @@ static int ov5640_init_cfg(struct v4l2_subdev *sd,
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_core_ops ov5640_core_ops = {
|
||||
.s_power = ov5640_s_power,
|
||||
.log_status = v4l2_ctrl_subdev_log_status,
|
||||
.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
|
||||
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
|
||||
@@ -3770,26 +3777,20 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
|
||||
int ret = 0;
|
||||
u16 chip_id;
|
||||
|
||||
ret = ov5640_set_power_on(sensor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "%s: failed to read chip identifier\n",
|
||||
__func__);
|
||||
goto power_off;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (chip_id != 0x5640) {
|
||||
dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x\n",
|
||||
__func__, chip_id);
|
||||
ret = -ENXIO;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
power_off:
|
||||
ov5640_set_power_off(sensor);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ov5640_probe(struct i2c_client *client)
|
||||
@@ -3880,26 +3881,43 @@ static int ov5640_probe(struct i2c_client *client)
|
||||
|
||||
ret = ov5640_get_regulators(sensor);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto entity_cleanup;
|
||||
|
||||
mutex_init(&sensor->lock);
|
||||
|
||||
ret = ov5640_check_chip_id(sensor);
|
||||
if (ret)
|
||||
goto entity_cleanup;
|
||||
|
||||
ret = ov5640_init_controls(sensor);
|
||||
if (ret)
|
||||
goto entity_cleanup;
|
||||
|
||||
ret = ov5640_sensor_resume(dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to power on\n");
|
||||
goto entity_cleanup;
|
||||
}
|
||||
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_get_noresume(dev);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
ret = ov5640_check_chip_id(sensor);
|
||||
if (ret)
|
||||
goto err_pm_runtime;
|
||||
|
||||
ret = v4l2_async_register_subdev_sensor(&sensor->sd);
|
||||
if (ret)
|
||||
goto free_ctrls;
|
||||
goto err_pm_runtime;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(dev, 1000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
free_ctrls:
|
||||
err_pm_runtime:
|
||||
pm_runtime_put_noidle(dev);
|
||||
pm_runtime_disable(dev);
|
||||
v4l2_ctrl_handler_free(&sensor->ctrls.handler);
|
||||
ov5640_sensor_suspend(dev);
|
||||
entity_cleanup:
|
||||
media_entity_cleanup(&sensor->sd.entity);
|
||||
mutex_destroy(&sensor->lock);
|
||||
@@ -3910,6 +3928,12 @@ static void ov5640_remove(struct i2c_client *client)
|
||||
{
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct ov5640_dev *sensor = to_ov5640_dev(sd);
|
||||
struct device *dev = &client->dev;
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
ov5640_sensor_suspend(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
|
||||
v4l2_async_unregister_subdev(&sensor->sd);
|
||||
media_entity_cleanup(&sensor->sd.entity);
|
||||
@@ -3917,6 +3941,10 @@ static void ov5640_remove(struct i2c_client *client)
|
||||
mutex_destroy(&sensor->lock);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ov5640_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(ov5640_sensor_suspend, ov5640_sensor_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct i2c_device_id ov5640_id[] = {
|
||||
{"ov5640", 0},
|
||||
{},
|
||||
@@ -3933,6 +3961,7 @@ static struct i2c_driver ov5640_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "ov5640",
|
||||
.of_match_table = ov5640_dt_ids,
|
||||
.pm = &ov5640_pm_ops,
|
||||
},
|
||||
.id_table = ov5640_id,
|
||||
.probe_new = ov5640_probe,
|
||||
|
||||
@@ -3034,11 +3034,13 @@ static int ov8865_probe(struct i2c_client *client)
|
||||
&rate);
|
||||
if (!ret && sensor->extclk) {
|
||||
ret = clk_set_rate(sensor->extclk, rate);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to set clock rate\n");
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "failed to set clock rate\n");
|
||||
goto error_endpoint;
|
||||
}
|
||||
} else if (ret && !sensor->extclk) {
|
||||
return dev_err_probe(dev, ret, "invalid clock config\n");
|
||||
dev_err_probe(dev, ret, "invalid clock config\n");
|
||||
goto error_endpoint;
|
||||
}
|
||||
|
||||
sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
|
||||
|
||||
@@ -581,7 +581,7 @@ static void __media_device_unregister_entity(struct media_entity *entity)
|
||||
struct media_device *mdev = entity->graph_obj.mdev;
|
||||
struct media_link *link, *tmp;
|
||||
struct media_interface *intf;
|
||||
unsigned int i;
|
||||
struct media_pad *iter;
|
||||
|
||||
ida_free(&mdev->entity_internal_idx, entity->internal_idx);
|
||||
|
||||
@@ -597,8 +597,8 @@ static void __media_device_unregister_entity(struct media_entity *entity)
|
||||
__media_entity_remove_links(entity);
|
||||
|
||||
/* Remove all pads that belong to this entity */
|
||||
for (i = 0; i < entity->num_pads; i++)
|
||||
media_gobj_destroy(&entity->pads[i].graph_obj);
|
||||
media_entity_for_each_pad(entity, iter)
|
||||
media_gobj_destroy(&iter->graph_obj);
|
||||
|
||||
/* Remove the entity */
|
||||
media_gobj_destroy(&entity->graph_obj);
|
||||
@@ -610,7 +610,7 @@ int __must_check media_device_register_entity(struct media_device *mdev,
|
||||
struct media_entity *entity)
|
||||
{
|
||||
struct media_entity_notify *notify, *next;
|
||||
unsigned int i;
|
||||
struct media_pad *iter;
|
||||
int ret;
|
||||
|
||||
if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
|
||||
@@ -639,9 +639,8 @@ int __must_check media_device_register_entity(struct media_device *mdev,
|
||||
media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
|
||||
|
||||
/* Initialize objects at the pads */
|
||||
for (i = 0; i < entity->num_pads; i++)
|
||||
media_gobj_create(mdev, MEDIA_GRAPH_PAD,
|
||||
&entity->pads[i].graph_obj);
|
||||
media_entity_for_each_pad(entity, iter)
|
||||
media_gobj_create(mdev, MEDIA_GRAPH_PAD, &iter->graph_obj);
|
||||
|
||||
/* invoke entity_notify callbacks */
|
||||
list_for_each_entry_safe(notify, next, &mdev->entity_notify, list)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -339,7 +339,7 @@ void cx18_av_std_setup(struct cx18 *cx)
|
||||
|
||||
/*
|
||||
* For a 13.5 Mpps clock and 15,625 Hz line rate, a line is
|
||||
* is 864 pixels = 720 active + 144 blanking. ITU-R BT.601
|
||||
* 864 pixels = 720 active + 144 blanking. ITU-R BT.601
|
||||
* specifies 12 luma clock periods or ~ 0.9 * 13.5 Mpps after
|
||||
* the end of active video to start a horizontal line, so that
|
||||
* leaves 132 pixels of hblank to ignore.
|
||||
@@ -399,7 +399,7 @@ void cx18_av_std_setup(struct cx18 *cx)
|
||||
|
||||
/*
|
||||
* For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
|
||||
* is 858 pixels = 720 active + 138 blanking. The Hsync leading
|
||||
* 858 pixels = 720 active + 138 blanking. The Hsync leading
|
||||
* edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
|
||||
* end of active video, leaving 122 pixels of hblank to ignore
|
||||
* before active video starts.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user