aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-05-31 09:38:23 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-28 14:25:43 -0400
commitf7354e6c230ec62d221e51aa3f970fd3d5eb2067 (patch)
treef71cb2eefb2f3df346df91f0bcb5eb8e1f8342d0 /drivers/media/platform
parent086eca2905d0d1ea6b5e22d62648c6b818c51846 (diff)
[media] exynos4-is: Add support for Exynos5250 MIPI-CSIS
Add compatible property for the Exynos5250 and enable the frame start and frame end interrupts. These interrupts are needed for the Exynos5 FIMC-IS firmware. The driver enables those interrupt only where available, depending on the 'compatible' property. This can be optimized further, by exposing some API at the subdev driver, so the host driver can enable extra interrupts only for the image processing chains involving FIMC-IS. Signed-off-by: Shaik Ameer Basha <shaik.ameer@samsung.com> 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>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 254d70fe762a..0914230b42de 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver 2 * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
3 * 3 *
4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. 4 * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com> 5 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -66,11 +66,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
66 66
67/* Interrupt mask */ 67/* Interrupt mask */
68#define S5PCSIS_INTMSK 0x10 68#define S5PCSIS_INTMSK 0x10
69#define S5PCSIS_INTMSK_EN_ALL 0xf000103f
70#define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31) 69#define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31)
71#define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30) 70#define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30)
72#define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29) 71#define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29)
73#define S5PCSIS_INTMSK_ODD_AFTER (1 << 28) 72#define S5PCSIS_INTMSK_ODD_AFTER (1 << 28)
73#define S5PCSIS_INTMSK_FRAME_START (1 << 27)
74#define S5PCSIS_INTMSK_FRAME_END (1 << 26)
74#define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12) 75#define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12)
75#define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5) 76#define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5)
76#define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4) 77#define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4)
@@ -78,6 +79,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
78#define S5PCSIS_INTMSK_ERR_ECC (1 << 2) 79#define S5PCSIS_INTMSK_ERR_ECC (1 << 2)
79#define S5PCSIS_INTMSK_ERR_CRC (1 << 1) 80#define S5PCSIS_INTMSK_ERR_CRC (1 << 1)
80#define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0) 81#define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0)
82#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL 0xf000103f
83#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL 0xfc00103f
81 84
82/* Interrupt source */ 85/* Interrupt source */
83#define S5PCSIS_INTSRC 0x14 86#define S5PCSIS_INTSRC 0x14
@@ -88,6 +91,8 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
88#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28) 91#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
89#define S5PCSIS_INTSRC_ODD (0x3 << 28) 92#define S5PCSIS_INTSRC_ODD (0x3 << 28)
90#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28) 93#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xff << 28)
94#define S5PCSIS_INTSRC_FRAME_START (1 << 27)
95#define S5PCSIS_INTSRC_FRAME_END (1 << 26)
91#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12) 96#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
92#define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5) 97#define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5)
93#define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4) 98#define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4)
@@ -151,6 +156,9 @@ static const struct s5pcsis_event s5pcsis_events[] = {
151 { S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" }, 156 { S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
152 { S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" }, 157 { S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
153 { S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" }, 158 { S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
159 /* Frame start/end */
160 { S5PCSIS_INTSRC_FRAME_START, "Frame Start" },
161 { S5PCSIS_INTSRC_FRAME_END, "Frame End" },
154}; 162};
155#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events) 163#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
156 164
@@ -159,6 +167,11 @@ struct csis_pktbuf {
159 unsigned int len; 167 unsigned int len;
160}; 168};
161 169
170struct csis_drvdata {
171 /* Mask of all used interrupts in S5PCSIS_INTMSK register */
172 u32 interrupt_mask;
173};
174
162/** 175/**
163 * struct csis_state - the driver's internal state data structure 176 * struct csis_state - the driver's internal state data structure
164 * @lock: mutex serializing the subdev and power management operations, 177 * @lock: mutex serializing the subdev and power management operations,
@@ -171,6 +184,7 @@ struct csis_pktbuf {
171 * @supplies: CSIS regulator supplies 184 * @supplies: CSIS regulator supplies
172 * @clock: CSIS clocks 185 * @clock: CSIS clocks
173 * @irq: requested s5p-mipi-csis irq number 186 * @irq: requested s5p-mipi-csis irq number
187 * @interrupt_mask: interrupt mask of the all used interrupts
174 * @flags: the state variable for power and streaming control 188 * @flags: the state variable for power and streaming control
175 * @clock_frequency: device bus clock frequency 189 * @clock_frequency: device bus clock frequency
176 * @hs_settle: HS-RX settle time 190 * @hs_settle: HS-RX settle time
@@ -193,6 +207,7 @@ struct csis_state {
193 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES]; 207 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
194 struct clk *clock[NUM_CSIS_CLOCKS]; 208 struct clk *clock[NUM_CSIS_CLOCKS];
195 int irq; 209 int irq;
210 u32 interrupt_mask;
196 u32 flags; 211 u32 flags;
197 212
198 u32 clk_frequency; 213 u32 clk_frequency;
@@ -274,9 +289,10 @@ static const struct csis_pix_format *find_csis_format(
274static void s5pcsis_enable_interrupts(struct csis_state *state, bool on) 289static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
275{ 290{
276 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK); 291 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
277 292 if (on)
278 val = on ? val | S5PCSIS_INTMSK_EN_ALL : 293 val |= state->interrupt_mask;
279 val & ~S5PCSIS_INTMSK_EN_ALL; 294 else
295 val &= ~state->interrupt_mask;
280 s5pcsis_write(state, S5PCSIS_INTMSK, val); 296 s5pcsis_write(state, S5PCSIS_INTMSK, val);
281} 297}
282 298
@@ -771,8 +787,12 @@ static int s5pcsis_parse_dt(struct platform_device *pdev,
771#define s5pcsis_parse_dt(pdev, state) (-ENOSYS) 787#define s5pcsis_parse_dt(pdev, state) (-ENOSYS)
772#endif 788#endif
773 789
790static const struct of_device_id s5pcsis_of_match[];
791
774static int s5pcsis_probe(struct platform_device *pdev) 792static int s5pcsis_probe(struct platform_device *pdev)
775{ 793{
794 const struct of_device_id *of_id;
795 const struct csis_drvdata *drv_data;
776 struct device *dev = &pdev->dev; 796 struct device *dev = &pdev->dev;
777 struct resource *mem_res; 797 struct resource *mem_res;
778 struct csis_state *state; 798 struct csis_state *state;
@@ -787,10 +807,19 @@ static int s5pcsis_probe(struct platform_device *pdev)
787 spin_lock_init(&state->slock); 807 spin_lock_init(&state->slock);
788 state->pdev = pdev; 808 state->pdev = pdev;
789 809
790 if (dev->of_node) 810 if (dev->of_node) {
811 of_id = of_match_node(s5pcsis_of_match, dev->of_node);
812 if (WARN_ON(of_id == NULL))
813 return -EINVAL;
814
815 drv_data = of_id->data;
816 state->interrupt_mask = drv_data->interrupt_mask;
817
791 ret = s5pcsis_parse_dt(pdev, state); 818 ret = s5pcsis_parse_dt(pdev, state);
792 else 819 } else {
793 ret = s5pcsis_get_platform_data(pdev, state); 820 ret = s5pcsis_get_platform_data(pdev, state);
821 }
822
794 if (ret < 0) 823 if (ret < 0)
795 return ret; 824 return ret;
796 825
@@ -994,9 +1023,25 @@ static const struct dev_pm_ops s5pcsis_pm_ops = {
994 SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume) 1023 SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
995}; 1024};
996 1025
1026static const struct csis_drvdata exynos4_csis_drvdata = {
1027 .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
1028};
1029
1030static const struct csis_drvdata exynos5_csis_drvdata = {
1031 .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
1032};
1033
997static const struct of_device_id s5pcsis_of_match[] = { 1034static const struct of_device_id s5pcsis_of_match[] = {
998 { .compatible = "samsung,s5pv210-csis" }, 1035 {
999 { .compatible = "samsung,exynos4210-csis" }, 1036 .compatible = "samsung,s5pv210-csis",
1037 .data = &exynos4_csis_drvdata,
1038 }, {
1039 .compatible = "samsung,exynos4210-csis",
1040 .data = &exynos4_csis_drvdata,
1041 }, {
1042 .compatible = "samsung,exynos5250-csis",
1043 .data = &exynos5_csis_drvdata,
1044 },
1000 { /* sentinel */ }, 1045 { /* sentinel */ },
1001}; 1046};
1002MODULE_DEVICE_TABLE(of, s5pcsis_of_match); 1047MODULE_DEVICE_TABLE(of, s5pcsis_of_match);