mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
[media] s5p-csis: Add device tree support
This patch support for binding the driver to the MIPI-CSIS devices instantiated from device tree and parsing the SoC and board specific properties. The MIPI CSI-2 channel is determined by the value of reg property placed in csis' port subnode. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
ee12b04910
commit
02399e35e6
@ -0,0 +1,81 @@
|
|||||||
|
Samsung S5P/EXYNOS SoC series MIPI CSI-2 receiver (MIPI CSIS)
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : "samsung,s5pv210-csis" for S5PV210 (S5PC110),
|
||||||
|
"samsung,exynos4210-csis" for Exynos4210 (S5PC210),
|
||||||
|
"samsung,exynos4212-csis" for Exynos4212/Exynos4412
|
||||||
|
SoC series;
|
||||||
|
- reg : offset and length of the register set for the device;
|
||||||
|
- interrupts : should contain MIPI CSIS interrupt; the format of the
|
||||||
|
interrupt specifier depends on the interrupt controller;
|
||||||
|
- bus-width : maximum number of data lanes supported (SoC specific);
|
||||||
|
- vddio-supply : MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V);
|
||||||
|
- vddcore-supply : MIPI CSIS Core voltage supply (e.g. 1.1V);
|
||||||
|
- clocks : list of clock specifiers, corresponding to entries in
|
||||||
|
clock-names property;
|
||||||
|
- clock-names : must contain "csis", "sclk_csis" entries, matching entries
|
||||||
|
in the clocks property.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- clock-frequency : The IP's main (system bus) clock frequency in Hz, default
|
||||||
|
value when this property is not specified is 166 MHz;
|
||||||
|
- samsung,csis-wclk : CSI-2 wrapper clock selection. If this property is present
|
||||||
|
external clock from CMU will be used, or the bus clock if
|
||||||
|
if it's not specified.
|
||||||
|
|
||||||
|
The device node should contain one 'port' child node with one child 'endpoint'
|
||||||
|
node, according to the bindings defined in Documentation/devicetree/bindings/
|
||||||
|
media/video-interfaces.txt. The following are properties specific to those nodes.
|
||||||
|
|
||||||
|
port node
|
||||||
|
---------
|
||||||
|
|
||||||
|
- reg : (required) must be 3 for camera C input (CSIS0) or 4 for
|
||||||
|
camera D input (CSIS1);
|
||||||
|
|
||||||
|
endpoint node
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- data-lanes : (required) an array specifying active physical MIPI-CSI2
|
||||||
|
data input lanes and their mapping to logical lanes; the
|
||||||
|
array's content is unused, only its length is meaningful;
|
||||||
|
|
||||||
|
- samsung,csis-hs-settle : (optional) differential receiver (HS-RX) settle time;
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
reg0: regulator@0 {
|
||||||
|
};
|
||||||
|
|
||||||
|
reg1: regulator@1 {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SoC properties */
|
||||||
|
|
||||||
|
csis_0: csis@11880000 {
|
||||||
|
compatible = "samsung,exynos4210-csis";
|
||||||
|
reg = <0x11880000 0x1000>;
|
||||||
|
interrupts = <0 78 0>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Board properties */
|
||||||
|
|
||||||
|
csis_0: csis@11880000 {
|
||||||
|
clock-frequency = <166000000>;
|
||||||
|
vddio-supply = <®0>;
|
||||||
|
vddcore-supply = <®1>;
|
||||||
|
port {
|
||||||
|
reg = <3>; /* 3 - CSIS0, 4 - CSIS1 */
|
||||||
|
csis0_ep: endpoint {
|
||||||
|
remote-endpoint = <...>;
|
||||||
|
data-lanes = <1>, <2>;
|
||||||
|
samsung,csis-hs-settle = <12>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -19,14 +19,18 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_data/mipi-csis.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
#include <media/s5p_fimc.h>
|
||||||
|
#include <media/v4l2-of.h>
|
||||||
#include <media/v4l2-subdev.h>
|
#include <media/v4l2-subdev.h>
|
||||||
#include <linux/platform_data/mipi-csis.h>
|
|
||||||
#include "mipi-csis.h"
|
#include "mipi-csis.h"
|
||||||
|
|
||||||
static int debug;
|
static int debug;
|
||||||
@ -113,6 +117,7 @@ static char *csi_clock_name[] = {
|
|||||||
[CSIS_CLK_GATE] = "csis",
|
[CSIS_CLK_GATE] = "csis",
|
||||||
};
|
};
|
||||||
#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
|
#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
|
||||||
|
#define DEFAULT_SCLK_CSIS_FREQ 166000000UL
|
||||||
|
|
||||||
static const char * const csis_supply_name[] = {
|
static const char * const csis_supply_name[] = {
|
||||||
"vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
|
"vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
|
||||||
@ -167,6 +172,11 @@ struct csis_pktbuf {
|
|||||||
* @clock: CSIS clocks
|
* @clock: CSIS clocks
|
||||||
* @irq: requested s5p-mipi-csis irq number
|
* @irq: requested s5p-mipi-csis irq number
|
||||||
* @flags: the state variable for power and streaming control
|
* @flags: the state variable for power and streaming control
|
||||||
|
* @clock_frequency: device bus clock frequency
|
||||||
|
* @hs_settle: HS-RX settle time
|
||||||
|
* @num_lanes: number of MIPI-CSI data lanes used
|
||||||
|
* @max_num_lanes: maximum number of MIPI-CSI data lanes supported
|
||||||
|
* @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM
|
||||||
* @csis_fmt: current CSIS pixel format
|
* @csis_fmt: current CSIS pixel format
|
||||||
* @format: common media bus format for the source and sink pad
|
* @format: common media bus format for the source and sink pad
|
||||||
* @slock: spinlock protecting structure members below
|
* @slock: spinlock protecting structure members below
|
||||||
@ -184,6 +194,13 @@ struct csis_state {
|
|||||||
struct clk *clock[NUM_CSIS_CLOCKS];
|
struct clk *clock[NUM_CSIS_CLOCKS];
|
||||||
int irq;
|
int irq;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|
||||||
|
u32 clk_frequency;
|
||||||
|
u32 hs_settle;
|
||||||
|
u32 num_lanes;
|
||||||
|
u32 max_num_lanes;
|
||||||
|
u8 wclk_ext;
|
||||||
|
|
||||||
const struct csis_pix_format *csis_fmt;
|
const struct csis_pix_format *csis_fmt;
|
||||||
struct v4l2_mbus_framefmt format;
|
struct v4l2_mbus_framefmt format;
|
||||||
|
|
||||||
@ -273,7 +290,6 @@ static void s5pcsis_reset(struct csis_state *state)
|
|||||||
|
|
||||||
static void s5pcsis_system_enable(struct csis_state *state, int on)
|
static void s5pcsis_system_enable(struct csis_state *state, int on)
|
||||||
{
|
{
|
||||||
struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
|
|
||||||
u32 val, mask;
|
u32 val, mask;
|
||||||
|
|
||||||
val = s5pcsis_read(state, S5PCSIS_CTRL);
|
val = s5pcsis_read(state, S5PCSIS_CTRL);
|
||||||
@ -286,7 +302,7 @@ static void s5pcsis_system_enable(struct csis_state *state, int on)
|
|||||||
val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
|
val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
|
||||||
val &= ~S5PCSIS_DPHYCTRL_ENABLE;
|
val &= ~S5PCSIS_DPHYCTRL_ENABLE;
|
||||||
if (on) {
|
if (on) {
|
||||||
mask = (1 << (pdata->lanes + 1)) - 1;
|
mask = (1 << (state->num_lanes + 1)) - 1;
|
||||||
val |= (mask & S5PCSIS_DPHYCTRL_ENABLE);
|
val |= (mask & S5PCSIS_DPHYCTRL_ENABLE);
|
||||||
}
|
}
|
||||||
s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
|
s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
|
||||||
@ -321,15 +337,14 @@ static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
|
|||||||
|
|
||||||
static void s5pcsis_set_params(struct csis_state *state)
|
static void s5pcsis_set_params(struct csis_state *state)
|
||||||
{
|
{
|
||||||
struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
|
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
val = s5pcsis_read(state, S5PCSIS_CONFIG);
|
val = s5pcsis_read(state, S5PCSIS_CONFIG);
|
||||||
val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
|
val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1);
|
||||||
s5pcsis_write(state, S5PCSIS_CONFIG, val);
|
s5pcsis_write(state, S5PCSIS_CONFIG, val);
|
||||||
|
|
||||||
__s5pcsis_set_format(state);
|
__s5pcsis_set_format(state);
|
||||||
s5pcsis_set_hsync_settle(state, pdata->hs_settle);
|
s5pcsis_set_hsync_settle(state, state->hs_settle);
|
||||||
|
|
||||||
val = s5pcsis_read(state, S5PCSIS_CTRL);
|
val = s5pcsis_read(state, S5PCSIS_CTRL);
|
||||||
if (state->csis_fmt->data_alignment == 32)
|
if (state->csis_fmt->data_alignment == 32)
|
||||||
@ -338,7 +353,7 @@ static void s5pcsis_set_params(struct csis_state *state)
|
|||||||
val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
|
val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
|
||||||
|
|
||||||
val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
|
val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
|
||||||
if (pdata->wclk_source)
|
if (state->wclk_ext)
|
||||||
val |= S5PCSIS_CTRL_WCLK_EXTCLK;
|
val |= S5PCSIS_CTRL_WCLK_EXTCLK;
|
||||||
s5pcsis_write(state, S5PCSIS_CTRL, val);
|
s5pcsis_write(state, S5PCSIS_CTRL, val);
|
||||||
|
|
||||||
@ -701,52 +716,111 @@ static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int s5pcsis_get_platform_data(struct platform_device *pdev,
|
||||||
|
struct csis_state *state)
|
||||||
|
{
|
||||||
|
struct s5p_platform_mipi_csis *pdata = pdev->dev.platform_data;
|
||||||
|
|
||||||
|
if (pdata == NULL) {
|
||||||
|
dev_err(&pdev->dev, "Platform data not specified\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->clk_frequency = pdata->clk_rate;
|
||||||
|
state->num_lanes = pdata->lanes;
|
||||||
|
state->hs_settle = pdata->hs_settle;
|
||||||
|
state->index = max(0, pdev->id);
|
||||||
|
state->max_num_lanes = state->index ? CSIS1_MAX_LANES :
|
||||||
|
CSIS0_MAX_LANES;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static int s5pcsis_parse_dt(struct platform_device *pdev,
|
||||||
|
struct csis_state *state)
|
||||||
|
{
|
||||||
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
struct v4l2_of_endpoint endpoint;
|
||||||
|
|
||||||
|
if (of_property_read_u32(node, "clock-frequency",
|
||||||
|
&state->clk_frequency))
|
||||||
|
state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
|
||||||
|
if (of_property_read_u32(node, "bus-width",
|
||||||
|
&state->max_num_lanes))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
node = v4l2_of_get_next_endpoint(node, NULL);
|
||||||
|
if (!node) {
|
||||||
|
dev_err(&pdev->dev, "No port node at %s\n",
|
||||||
|
node->full_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* Get port node and validate MIPI-CSI channel id. */
|
||||||
|
v4l2_of_parse_endpoint(node, &endpoint);
|
||||||
|
|
||||||
|
state->index = endpoint.port - FIMC_INPUT_MIPI_CSI2_0;
|
||||||
|
if (state->index < 0 || state->index >= CSIS_MAX_ENTITIES)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
/* Get MIPI CSI-2 bus configration from the endpoint node. */
|
||||||
|
of_property_read_u32(node, "samsung,csis-hs-settle",
|
||||||
|
&state->hs_settle);
|
||||||
|
state->wclk_ext = of_property_read_bool(node,
|
||||||
|
"samsung,csis-wclk");
|
||||||
|
|
||||||
|
state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
|
||||||
|
|
||||||
|
of_node_put(node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
|
||||||
|
#endif
|
||||||
|
|
||||||
static int s5pcsis_probe(struct platform_device *pdev)
|
static int s5pcsis_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct s5p_platform_mipi_csis *pdata;
|
struct device *dev = &pdev->dev;
|
||||||
struct resource *mem_res;
|
struct resource *mem_res;
|
||||||
struct csis_state *state;
|
struct csis_state *state;
|
||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
|
state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
|
||||||
if (!state)
|
if (!state)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_init(&state->lock);
|
mutex_init(&state->lock);
|
||||||
spin_lock_init(&state->slock);
|
spin_lock_init(&state->slock);
|
||||||
|
|
||||||
state->pdev = pdev;
|
state->pdev = pdev;
|
||||||
state->index = max(0, pdev->id);
|
|
||||||
|
|
||||||
pdata = pdev->dev.platform_data;
|
if (dev->of_node)
|
||||||
if (pdata == NULL) {
|
ret = s5pcsis_parse_dt(pdev, state);
|
||||||
dev_err(&pdev->dev, "Platform data not fully specified\n");
|
else
|
||||||
return -EINVAL;
|
ret = s5pcsis_get_platform_data(pdev, state);
|
||||||
}
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if ((state->index == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
|
if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) {
|
||||||
pdata->lanes > CSIS0_MAX_LANES) {
|
dev_err(dev, "Unsupported number of data lanes: %d (max. %d)\n",
|
||||||
dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
|
state->num_lanes, state->max_num_lanes);
|
||||||
pdata->lanes);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
state->regs = devm_ioremap_resource(&pdev->dev, mem_res);
|
state->regs = devm_ioremap_resource(dev, mem_res);
|
||||||
if (IS_ERR(state->regs))
|
if (IS_ERR(state->regs))
|
||||||
return PTR_ERR(state->regs);
|
return PTR_ERR(state->regs);
|
||||||
|
|
||||||
state->irq = platform_get_irq(pdev, 0);
|
state->irq = platform_get_irq(pdev, 0);
|
||||||
if (state->irq < 0) {
|
if (state->irq < 0) {
|
||||||
dev_err(&pdev->dev, "Failed to get irq\n");
|
dev_err(dev, "Failed to get irq\n");
|
||||||
return state->irq;
|
return state->irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
|
for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
|
||||||
state->supplies[i].supply = csis_supply_name[i];
|
state->supplies[i].supply = csis_supply_name[i];
|
||||||
|
|
||||||
ret = devm_regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
|
ret = devm_regulator_bulk_get(dev, CSIS_NUM_SUPPLIES,
|
||||||
state->supplies);
|
state->supplies);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -755,11 +829,11 @@ static int s5pcsis_probe(struct platform_device *pdev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (pdata->clk_rate)
|
if (state->clk_frequency)
|
||||||
ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
|
ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
|
||||||
pdata->clk_rate);
|
state->clk_frequency);
|
||||||
else
|
else
|
||||||
dev_WARN(&pdev->dev, "No clock frequency specified!\n");
|
dev_WARN(dev, "No clock frequency specified!\n");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto e_clkput;
|
goto e_clkput;
|
||||||
|
|
||||||
@ -767,16 +841,17 @@ static int s5pcsis_probe(struct platform_device *pdev)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto e_clkput;
|
goto e_clkput;
|
||||||
|
|
||||||
ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
|
ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler,
|
||||||
0, dev_name(&pdev->dev), state);
|
0, dev_name(dev), state);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Interrupt request failed\n");
|
dev_err(dev, "Interrupt request failed\n");
|
||||||
goto e_clkdis;
|
goto e_clkdis;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
|
v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
|
||||||
state->sd.owner = THIS_MODULE;
|
state->sd.owner = THIS_MODULE;
|
||||||
strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
|
snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d",
|
||||||
|
CSIS_SUBDEV_NAME, state->index);
|
||||||
state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||||
state->csis_fmt = &s5pcsis_formats[0];
|
state->csis_fmt = &s5pcsis_formats[0];
|
||||||
|
|
||||||
@ -796,10 +871,12 @@ static int s5pcsis_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
/* .. and a pointer to the subdev. */
|
/* .. and a pointer to the subdev. */
|
||||||
platform_set_drvdata(pdev, &state->sd);
|
platform_set_drvdata(pdev, &state->sd);
|
||||||
|
|
||||||
memcpy(state->events, s5pcsis_events, sizeof(state->events));
|
memcpy(state->events, s5pcsis_events, sizeof(state->events));
|
||||||
|
pm_runtime_enable(dev);
|
||||||
|
|
||||||
pm_runtime_enable(&pdev->dev);
|
dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n",
|
||||||
|
state->num_lanes, state->hs_settle, state->wclk_ext,
|
||||||
|
state->clk_frequency);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
e_clkdis:
|
e_clkdis:
|
||||||
@ -923,13 +1000,21 @@ static const struct dev_pm_ops s5pcsis_pm_ops = {
|
|||||||
SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
|
SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id s5pcsis_of_match[] = {
|
||||||
|
{ .compatible = "samsung,s5pv210-csis" },
|
||||||
|
{ .compatible = "samsung,exynos4210-csis" },
|
||||||
|
{ /* sentinel */ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
|
||||||
|
|
||||||
static struct platform_driver s5pcsis_driver = {
|
static struct platform_driver s5pcsis_driver = {
|
||||||
.probe = s5pcsis_probe,
|
.probe = s5pcsis_probe,
|
||||||
.remove = s5pcsis_remove,
|
.remove = s5pcsis_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = CSIS_DRIVER_NAME,
|
.of_match_table = s5pcsis_of_match,
|
||||||
.owner = THIS_MODULE,
|
.name = CSIS_DRIVER_NAME,
|
||||||
.pm = &s5pcsis_pm_ops,
|
.owner = THIS_MODULE,
|
||||||
|
.pm = &s5pcsis_pm_ops,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define S5P_MIPI_CSIS_H_
|
#define S5P_MIPI_CSIS_H_
|
||||||
|
|
||||||
#define CSIS_DRIVER_NAME "s5p-mipi-csis"
|
#define CSIS_DRIVER_NAME "s5p-mipi-csis"
|
||||||
|
#define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME
|
||||||
#define CSIS_MAX_ENTITIES 2
|
#define CSIS_MAX_ENTITIES 2
|
||||||
#define CSIS0_MAX_LANES 4
|
#define CSIS0_MAX_LANES 4
|
||||||
#define CSIS1_MAX_LANES 2
|
#define CSIS1_MAX_LANES 2
|
||||||
|
@ -14,6 +14,19 @@
|
|||||||
|
|
||||||
#include <media/media-entity.h>
|
#include <media/media-entity.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumeration of data inputs to the camera subsystem.
|
||||||
|
*/
|
||||||
|
enum fimc_input {
|
||||||
|
FIMC_INPUT_PARALLEL_0 = 1,
|
||||||
|
FIMC_INPUT_PARALLEL_1,
|
||||||
|
FIMC_INPUT_MIPI_CSI2_0 = 3,
|
||||||
|
FIMC_INPUT_MIPI_CSI2_1,
|
||||||
|
FIMC_INPUT_WRITEBACK_A = 5,
|
||||||
|
FIMC_INPUT_WRITEBACK_B,
|
||||||
|
FIMC_INPUT_WRITEBACK_ISP = 5,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumeration of the FIMC data bus types.
|
* Enumeration of the FIMC data bus types.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user