diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-03-26 07:20:30 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-31 09:42:58 -0400 |
commit | 02399e35e6bb716ce9636eba006b792362270034 (patch) | |
tree | 24ec7af43a7ee0c310bf6dd64457396875f7d268 | |
parent | ee12b049104118a58ac13da207a84c867191b17a (diff) |
[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>
-rw-r--r-- | Documentation/devicetree/bindings/media/samsung-mipi-csis.txt | 81 | ||||
-rw-r--r-- | drivers/media/platform/s5p-fimc/mipi-csis.c | 155 | ||||
-rw-r--r-- | drivers/media/platform/s5p-fimc/mipi-csis.h | 1 | ||||
-rw-r--r-- | include/media/s5p_fimc.h | 13 |
4 files changed, 215 insertions, 35 deletions
diff --git a/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt new file mode 100644 index 000000000000..5f8e28e2484f --- /dev/null +++ b/Documentation/devicetree/bindings/media/samsung-mipi-csis.txt | |||
@@ -0,0 +1,81 @@ | |||
1 | Samsung S5P/EXYNOS SoC series MIPI CSI-2 receiver (MIPI CSIS) | ||
2 | ------------------------------------------------------------- | ||
3 | |||
4 | Required properties: | ||
5 | |||
6 | - compatible : "samsung,s5pv210-csis" for S5PV210 (S5PC110), | ||
7 | "samsung,exynos4210-csis" for Exynos4210 (S5PC210), | ||
8 | "samsung,exynos4212-csis" for Exynos4212/Exynos4412 | ||
9 | SoC series; | ||
10 | - reg : offset and length of the register set for the device; | ||
11 | - interrupts : should contain MIPI CSIS interrupt; the format of the | ||
12 | interrupt specifier depends on the interrupt controller; | ||
13 | - bus-width : maximum number of data lanes supported (SoC specific); | ||
14 | - vddio-supply : MIPI CSIS I/O and PLL voltage supply (e.g. 1.8V); | ||
15 | - vddcore-supply : MIPI CSIS Core voltage supply (e.g. 1.1V); | ||
16 | - clocks : list of clock specifiers, corresponding to entries in | ||
17 | clock-names property; | ||
18 | - clock-names : must contain "csis", "sclk_csis" entries, matching entries | ||
19 | in the clocks property. | ||
20 | |||
21 | Optional properties: | ||
22 | |||
23 | - clock-frequency : The IP's main (system bus) clock frequency in Hz, default | ||
24 | value when this property is not specified is 166 MHz; | ||
25 | - samsung,csis-wclk : CSI-2 wrapper clock selection. If this property is present | ||
26 | external clock from CMU will be used, or the bus clock if | ||
27 | if it's not specified. | ||
28 | |||
29 | The device node should contain one 'port' child node with one child 'endpoint' | ||
30 | node, according to the bindings defined in Documentation/devicetree/bindings/ | ||
31 | media/video-interfaces.txt. The following are properties specific to those nodes. | ||
32 | |||
33 | port node | ||
34 | --------- | ||
35 | |||
36 | - reg : (required) must be 3 for camera C input (CSIS0) or 4 for | ||
37 | camera D input (CSIS1); | ||
38 | |||
39 | endpoint node | ||
40 | ------------- | ||
41 | |||
42 | - data-lanes : (required) an array specifying active physical MIPI-CSI2 | ||
43 | data input lanes and their mapping to logical lanes; the | ||
44 | array's content is unused, only its length is meaningful; | ||
45 | |||
46 | - samsung,csis-hs-settle : (optional) differential receiver (HS-RX) settle time; | ||
47 | |||
48 | |||
49 | Example: | ||
50 | |||
51 | reg0: regulator@0 { | ||
52 | }; | ||
53 | |||
54 | reg1: regulator@1 { | ||
55 | }; | ||
56 | |||
57 | /* SoC properties */ | ||
58 | |||
59 | csis_0: csis@11880000 { | ||
60 | compatible = "samsung,exynos4210-csis"; | ||
61 | reg = <0x11880000 0x1000>; | ||
62 | interrupts = <0 78 0>; | ||
63 | #address-cells = <1>; | ||
64 | #size-cells = <0>; | ||
65 | }; | ||
66 | |||
67 | /* Board properties */ | ||
68 | |||
69 | csis_0: csis@11880000 { | ||
70 | clock-frequency = <166000000>; | ||
71 | vddio-supply = <®0>; | ||
72 | vddcore-supply = <®1>; | ||
73 | port { | ||
74 | reg = <3>; /* 3 - CSIS0, 4 - CSIS1 */ | ||
75 | csis0_ep: endpoint { | ||
76 | remote-endpoint = <...>; | ||
77 | data-lanes = <1>, <2>; | ||
78 | samsung,csis-hs-settle = <12>; | ||
79 | }; | ||
80 | }; | ||
81 | }; | ||
diff --git a/drivers/media/platform/s5p-fimc/mipi-csis.c b/drivers/media/platform/s5p-fimc/mipi-csis.c index 981863d05aaa..8636bcddde1b 100644 --- a/drivers/media/platform/s5p-fimc/mipi-csis.c +++ b/drivers/media/platform/s5p-fimc/mipi-csis.c | |||
@@ -19,14 +19,18 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/memory.h> | 20 | #include <linux/memory.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/of.h> | ||
23 | #include <linux/platform_data/mipi-csis.h> | ||
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/pm_runtime.h> | 25 | #include <linux/pm_runtime.h> |
24 | #include <linux/regulator/consumer.h> | 26 | #include <linux/regulator/consumer.h> |
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
26 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
27 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
30 | #include <media/s5p_fimc.h> | ||
31 | #include <media/v4l2-of.h> | ||
28 | #include <media/v4l2-subdev.h> | 32 | #include <media/v4l2-subdev.h> |
29 | #include <linux/platform_data/mipi-csis.h> | 33 | |
30 | #include "mipi-csis.h" | 34 | #include "mipi-csis.h" |
31 | 35 | ||
32 | static int debug; | 36 | static int debug; |
@@ -113,6 +117,7 @@ static char *csi_clock_name[] = { | |||
113 | [CSIS_CLK_GATE] = "csis", | 117 | [CSIS_CLK_GATE] = "csis", |
114 | }; | 118 | }; |
115 | #define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name) | 119 | #define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name) |
120 | #define DEFAULT_SCLK_CSIS_FREQ 166000000UL | ||
116 | 121 | ||
117 | static const char * const csis_supply_name[] = { | 122 | static const char * const csis_supply_name[] = { |
118 | "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */ | 123 | "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */ |
@@ -167,6 +172,11 @@ struct csis_pktbuf { | |||
167 | * @clock: CSIS clocks | 172 | * @clock: CSIS clocks |
168 | * @irq: requested s5p-mipi-csis irq number | 173 | * @irq: requested s5p-mipi-csis irq number |
169 | * @flags: the state variable for power and streaming control | 174 | * @flags: the state variable for power and streaming control |
175 | * @clock_frequency: device bus clock frequency | ||
176 | * @hs_settle: HS-RX settle time | ||
177 | * @num_lanes: number of MIPI-CSI data lanes used | ||
178 | * @max_num_lanes: maximum number of MIPI-CSI data lanes supported | ||
179 | * @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM | ||
170 | * @csis_fmt: current CSIS pixel format | 180 | * @csis_fmt: current CSIS pixel format |
171 | * @format: common media bus format for the source and sink pad | 181 | * @format: common media bus format for the source and sink pad |
172 | * @slock: spinlock protecting structure members below | 182 | * @slock: spinlock protecting structure members below |
@@ -184,6 +194,13 @@ struct csis_state { | |||
184 | struct clk *clock[NUM_CSIS_CLOCKS]; | 194 | struct clk *clock[NUM_CSIS_CLOCKS]; |
185 | int irq; | 195 | int irq; |
186 | u32 flags; | 196 | u32 flags; |
197 | |||
198 | u32 clk_frequency; | ||
199 | u32 hs_settle; | ||
200 | u32 num_lanes; | ||
201 | u32 max_num_lanes; | ||
202 | u8 wclk_ext; | ||
203 | |||
187 | const struct csis_pix_format *csis_fmt; | 204 | const struct csis_pix_format *csis_fmt; |
188 | struct v4l2_mbus_framefmt format; | 205 | struct v4l2_mbus_framefmt format; |
189 | 206 | ||
@@ -273,7 +290,6 @@ static void s5pcsis_reset(struct csis_state *state) | |||
273 | 290 | ||
274 | static void s5pcsis_system_enable(struct csis_state *state, int on) | 291 | static void s5pcsis_system_enable(struct csis_state *state, int on) |
275 | { | 292 | { |
276 | struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data; | ||
277 | u32 val, mask; | 293 | u32 val, mask; |
278 | 294 | ||
279 | val = s5pcsis_read(state, S5PCSIS_CTRL); | 295 | val = s5pcsis_read(state, S5PCSIS_CTRL); |
@@ -286,7 +302,7 @@ static void s5pcsis_system_enable(struct csis_state *state, int on) | |||
286 | val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); | 302 | val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); |
287 | val &= ~S5PCSIS_DPHYCTRL_ENABLE; | 303 | val &= ~S5PCSIS_DPHYCTRL_ENABLE; |
288 | if (on) { | 304 | if (on) { |
289 | mask = (1 << (pdata->lanes + 1)) - 1; | 305 | mask = (1 << (state->num_lanes + 1)) - 1; |
290 | val |= (mask & S5PCSIS_DPHYCTRL_ENABLE); | 306 | val |= (mask & S5PCSIS_DPHYCTRL_ENABLE); |
291 | } | 307 | } |
292 | s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); | 308 | s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); |
@@ -321,15 +337,14 @@ static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle) | |||
321 | 337 | ||
322 | static void s5pcsis_set_params(struct csis_state *state) | 338 | static void s5pcsis_set_params(struct csis_state *state) |
323 | { | 339 | { |
324 | struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data; | ||
325 | u32 val; | 340 | u32 val; |
326 | 341 | ||
327 | val = s5pcsis_read(state, S5PCSIS_CONFIG); | 342 | val = s5pcsis_read(state, S5PCSIS_CONFIG); |
328 | val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1); | 343 | val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1); |
329 | s5pcsis_write(state, S5PCSIS_CONFIG, val); | 344 | s5pcsis_write(state, S5PCSIS_CONFIG, val); |
330 | 345 | ||
331 | __s5pcsis_set_format(state); | 346 | __s5pcsis_set_format(state); |
332 | s5pcsis_set_hsync_settle(state, pdata->hs_settle); | 347 | s5pcsis_set_hsync_settle(state, state->hs_settle); |
333 | 348 | ||
334 | val = s5pcsis_read(state, S5PCSIS_CTRL); | 349 | val = s5pcsis_read(state, S5PCSIS_CTRL); |
335 | if (state->csis_fmt->data_alignment == 32) | 350 | if (state->csis_fmt->data_alignment == 32) |
@@ -338,7 +353,7 @@ static void s5pcsis_set_params(struct csis_state *state) | |||
338 | val &= ~S5PCSIS_CTRL_ALIGN_32BIT; | 353 | val &= ~S5PCSIS_CTRL_ALIGN_32BIT; |
339 | 354 | ||
340 | val &= ~S5PCSIS_CTRL_WCLK_EXTCLK; | 355 | val &= ~S5PCSIS_CTRL_WCLK_EXTCLK; |
341 | if (pdata->wclk_source) | 356 | if (state->wclk_ext) |
342 | val |= S5PCSIS_CTRL_WCLK_EXTCLK; | 357 | val |= S5PCSIS_CTRL_WCLK_EXTCLK; |
343 | s5pcsis_write(state, S5PCSIS_CTRL, val); | 358 | s5pcsis_write(state, S5PCSIS_CTRL, val); |
344 | 359 | ||
@@ -701,52 +716,111 @@ static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id) | |||
701 | return IRQ_HANDLED; | 716 | return IRQ_HANDLED; |
702 | } | 717 | } |
703 | 718 | ||
719 | static int s5pcsis_get_platform_data(struct platform_device *pdev, | ||
720 | struct csis_state *state) | ||
721 | { | ||
722 | struct s5p_platform_mipi_csis *pdata = pdev->dev.platform_data; | ||
723 | |||
724 | if (pdata == NULL) { | ||
725 | dev_err(&pdev->dev, "Platform data not specified\n"); | ||
726 | return -EINVAL; | ||
727 | } | ||
728 | |||
729 | state->clk_frequency = pdata->clk_rate; | ||
730 | state->num_lanes = pdata->lanes; | ||
731 | state->hs_settle = pdata->hs_settle; | ||
732 | state->index = max(0, pdev->id); | ||
733 | state->max_num_lanes = state->index ? CSIS1_MAX_LANES : | ||
734 | CSIS0_MAX_LANES; | ||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | #ifdef CONFIG_OF | ||
739 | static int s5pcsis_parse_dt(struct platform_device *pdev, | ||
740 | struct csis_state *state) | ||
741 | { | ||
742 | struct device_node *node = pdev->dev.of_node; | ||
743 | struct v4l2_of_endpoint endpoint; | ||
744 | |||
745 | if (of_property_read_u32(node, "clock-frequency", | ||
746 | &state->clk_frequency)) | ||
747 | state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; | ||
748 | if (of_property_read_u32(node, "bus-width", | ||
749 | &state->max_num_lanes)) | ||
750 | return -EINVAL; | ||
751 | |||
752 | node = v4l2_of_get_next_endpoint(node, NULL); | ||
753 | if (!node) { | ||
754 | dev_err(&pdev->dev, "No port node at %s\n", | ||
755 | node->full_name); | ||
756 | return -EINVAL; | ||
757 | } | ||
758 | /* Get port node and validate MIPI-CSI channel id. */ | ||
759 | v4l2_of_parse_endpoint(node, &endpoint); | ||
760 | |||
761 | state->index = endpoint.port - FIMC_INPUT_MIPI_CSI2_0; | ||
762 | if (state->index < 0 || state->index >= CSIS_MAX_ENTITIES) | ||
763 | return -ENXIO; | ||
764 | |||
765 | /* Get MIPI CSI-2 bus configration from the endpoint node. */ | ||
766 | of_property_read_u32(node, "samsung,csis-hs-settle", | ||
767 | &state->hs_settle); | ||
768 | state->wclk_ext = of_property_read_bool(node, | ||
769 | "samsung,csis-wclk"); | ||
770 | |||
771 | state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes; | ||
772 | |||
773 | of_node_put(node); | ||
774 | return 0; | ||
775 | } | ||
776 | #else | ||
777 | #define s5pcsis_parse_dt(pdev, state) (-ENOSYS) | ||
778 | #endif | ||
779 | |||
704 | static int s5pcsis_probe(struct platform_device *pdev) | 780 | static int s5pcsis_probe(struct platform_device *pdev) |
705 | { | 781 | { |
706 | struct s5p_platform_mipi_csis *pdata; | 782 | struct device *dev = &pdev->dev; |
707 | struct resource *mem_res; | 783 | struct resource *mem_res; |
708 | struct csis_state *state; | 784 | struct csis_state *state; |
709 | int ret = -ENOMEM; | 785 | int ret = -ENOMEM; |
710 | int i; | 786 | int i; |
711 | 787 | ||
712 | state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); | 788 | state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); |
713 | if (!state) | 789 | if (!state) |
714 | return -ENOMEM; | 790 | return -ENOMEM; |
715 | 791 | ||
716 | mutex_init(&state->lock); | 792 | mutex_init(&state->lock); |
717 | spin_lock_init(&state->slock); | 793 | spin_lock_init(&state->slock); |
718 | |||
719 | state->pdev = pdev; | 794 | state->pdev = pdev; |
720 | state->index = max(0, pdev->id); | ||
721 | 795 | ||
722 | pdata = pdev->dev.platform_data; | 796 | if (dev->of_node) |
723 | if (pdata == NULL) { | 797 | ret = s5pcsis_parse_dt(pdev, state); |
724 | dev_err(&pdev->dev, "Platform data not fully specified\n"); | 798 | else |
725 | return -EINVAL; | 799 | ret = s5pcsis_get_platform_data(pdev, state); |
726 | } | 800 | if (ret < 0) |
801 | return ret; | ||
727 | 802 | ||
728 | if ((state->index == 1 && pdata->lanes > CSIS1_MAX_LANES) || | 803 | if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) { |
729 | pdata->lanes > CSIS0_MAX_LANES) { | 804 | dev_err(dev, "Unsupported number of data lanes: %d (max. %d)\n", |
730 | dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n", | 805 | state->num_lanes, state->max_num_lanes); |
731 | pdata->lanes); | ||
732 | return -EINVAL; | 806 | return -EINVAL; |
733 | } | 807 | } |
734 | 808 | ||
735 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 809 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
736 | state->regs = devm_ioremap_resource(&pdev->dev, mem_res); | 810 | state->regs = devm_ioremap_resource(dev, mem_res); |
737 | if (IS_ERR(state->regs)) | 811 | if (IS_ERR(state->regs)) |
738 | return PTR_ERR(state->regs); | 812 | return PTR_ERR(state->regs); |
739 | 813 | ||
740 | state->irq = platform_get_irq(pdev, 0); | 814 | state->irq = platform_get_irq(pdev, 0); |
741 | if (state->irq < 0) { | 815 | if (state->irq < 0) { |
742 | dev_err(&pdev->dev, "Failed to get irq\n"); | 816 | dev_err(dev, "Failed to get irq\n"); |
743 | return state->irq; | 817 | return state->irq; |
744 | } | 818 | } |
745 | 819 | ||
746 | for (i = 0; i < CSIS_NUM_SUPPLIES; i++) | 820 | for (i = 0; i < CSIS_NUM_SUPPLIES; i++) |
747 | state->supplies[i].supply = csis_supply_name[i]; | 821 | state->supplies[i].supply = csis_supply_name[i]; |
748 | 822 | ||
749 | ret = devm_regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES, | 823 | ret = devm_regulator_bulk_get(dev, CSIS_NUM_SUPPLIES, |
750 | state->supplies); | 824 | state->supplies); |
751 | if (ret) | 825 | if (ret) |
752 | return ret; | 826 | return ret; |
@@ -755,11 +829,11 @@ static int s5pcsis_probe(struct platform_device *pdev) | |||
755 | if (ret < 0) | 829 | if (ret < 0) |
756 | return ret; | 830 | return ret; |
757 | 831 | ||
758 | if (pdata->clk_rate) | 832 | if (state->clk_frequency) |
759 | ret = clk_set_rate(state->clock[CSIS_CLK_MUX], | 833 | ret = clk_set_rate(state->clock[CSIS_CLK_MUX], |
760 | pdata->clk_rate); | 834 | state->clk_frequency); |
761 | else | 835 | else |
762 | dev_WARN(&pdev->dev, "No clock frequency specified!\n"); | 836 | dev_WARN(dev, "No clock frequency specified!\n"); |
763 | if (ret < 0) | 837 | if (ret < 0) |
764 | goto e_clkput; | 838 | goto e_clkput; |
765 | 839 | ||
@@ -767,16 +841,17 @@ static int s5pcsis_probe(struct platform_device *pdev) | |||
767 | if (ret < 0) | 841 | if (ret < 0) |
768 | goto e_clkput; | 842 | goto e_clkput; |
769 | 843 | ||
770 | ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler, | 844 | ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler, |
771 | 0, dev_name(&pdev->dev), state); | 845 | 0, dev_name(dev), state); |
772 | if (ret) { | 846 | if (ret) { |
773 | dev_err(&pdev->dev, "Interrupt request failed\n"); | 847 | dev_err(dev, "Interrupt request failed\n"); |
774 | goto e_clkdis; | 848 | goto e_clkdis; |
775 | } | 849 | } |
776 | 850 | ||
777 | v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops); | 851 | v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops); |
778 | state->sd.owner = THIS_MODULE; | 852 | state->sd.owner = THIS_MODULE; |
779 | strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name)); | 853 | snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d", |
854 | CSIS_SUBDEV_NAME, state->index); | ||
780 | state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; | 855 | state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
781 | state->csis_fmt = &s5pcsis_formats[0]; | 856 | state->csis_fmt = &s5pcsis_formats[0]; |
782 | 857 | ||
@@ -796,10 +871,12 @@ static int s5pcsis_probe(struct platform_device *pdev) | |||
796 | 871 | ||
797 | /* .. and a pointer to the subdev. */ | 872 | /* .. and a pointer to the subdev. */ |
798 | platform_set_drvdata(pdev, &state->sd); | 873 | platform_set_drvdata(pdev, &state->sd); |
799 | |||
800 | memcpy(state->events, s5pcsis_events, sizeof(state->events)); | 874 | memcpy(state->events, s5pcsis_events, sizeof(state->events)); |
875 | pm_runtime_enable(dev); | ||
801 | 876 | ||
802 | pm_runtime_enable(&pdev->dev); | 877 | dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", |
878 | state->num_lanes, state->hs_settle, state->wclk_ext, | ||
879 | state->clk_frequency); | ||
803 | return 0; | 880 | return 0; |
804 | 881 | ||
805 | e_clkdis: | 882 | e_clkdis: |
@@ -923,13 +1000,21 @@ static const struct dev_pm_ops s5pcsis_pm_ops = { | |||
923 | SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume) | 1000 | SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume) |
924 | }; | 1001 | }; |
925 | 1002 | ||
1003 | static const struct of_device_id s5pcsis_of_match[] = { | ||
1004 | { .compatible = "samsung,s5pv210-csis" }, | ||
1005 | { .compatible = "samsung,exynos4210-csis" }, | ||
1006 | { /* sentinel */ }, | ||
1007 | }; | ||
1008 | MODULE_DEVICE_TABLE(of, s5pcsis_of_match); | ||
1009 | |||
926 | static struct platform_driver s5pcsis_driver = { | 1010 | static struct platform_driver s5pcsis_driver = { |
927 | .probe = s5pcsis_probe, | 1011 | .probe = s5pcsis_probe, |
928 | .remove = s5pcsis_remove, | 1012 | .remove = s5pcsis_remove, |
929 | .driver = { | 1013 | .driver = { |
930 | .name = CSIS_DRIVER_NAME, | 1014 | .of_match_table = s5pcsis_of_match, |
931 | .owner = THIS_MODULE, | 1015 | .name = CSIS_DRIVER_NAME, |
932 | .pm = &s5pcsis_pm_ops, | 1016 | .owner = THIS_MODULE, |
1017 | .pm = &s5pcsis_pm_ops, | ||
933 | }, | 1018 | }, |
934 | }; | 1019 | }; |
935 | 1020 | ||
diff --git a/drivers/media/platform/s5p-fimc/mipi-csis.h b/drivers/media/platform/s5p-fimc/mipi-csis.h index 2709286396e1..28c11c4085d8 100644 --- a/drivers/media/platform/s5p-fimc/mipi-csis.h +++ b/drivers/media/platform/s5p-fimc/mipi-csis.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #define S5P_MIPI_CSIS_H_ | 11 | #define S5P_MIPI_CSIS_H_ |
12 | 12 | ||
13 | #define CSIS_DRIVER_NAME "s5p-mipi-csis" | 13 | #define CSIS_DRIVER_NAME "s5p-mipi-csis" |
14 | #define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME | ||
14 | #define CSIS_MAX_ENTITIES 2 | 15 | #define CSIS_MAX_ENTITIES 2 |
15 | #define CSIS0_MAX_LANES 4 | 16 | #define CSIS0_MAX_LANES 4 |
16 | #define CSIS1_MAX_LANES 2 | 17 | #define CSIS1_MAX_LANES 2 |
diff --git a/include/media/s5p_fimc.h b/include/media/s5p_fimc.h index 28f3590aa031..d6dbb791f423 100644 --- a/include/media/s5p_fimc.h +++ b/include/media/s5p_fimc.h | |||
@@ -15,6 +15,19 @@ | |||
15 | #include <media/media-entity.h> | 15 | #include <media/media-entity.h> |
16 | 16 | ||
17 | /* | 17 | /* |
18 | * Enumeration of data inputs to the camera subsystem. | ||
19 | */ | ||
20 | enum fimc_input { | ||
21 | FIMC_INPUT_PARALLEL_0 = 1, | ||
22 | FIMC_INPUT_PARALLEL_1, | ||
23 | FIMC_INPUT_MIPI_CSI2_0 = 3, | ||
24 | FIMC_INPUT_MIPI_CSI2_1, | ||
25 | FIMC_INPUT_WRITEBACK_A = 5, | ||
26 | FIMC_INPUT_WRITEBACK_B, | ||
27 | FIMC_INPUT_WRITEBACK_ISP = 5, | ||
28 | }; | ||
29 | |||
30 | /* | ||
18 | * Enumeration of the FIMC data bus types. | 31 | * Enumeration of the FIMC data bus types. |
19 | */ | 32 | */ |
20 | enum fimc_bus_type { | 33 | enum fimc_bus_type { |