Commit | Line | Data |
---|---|---|
d3953223 | 1 | /* |
0c9204d3 | 2 | * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. |
d3953223 SN |
3 | * |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License version 2 as | |
6 | * published by the Free Software Foundation. | |
7 | */ | |
8 | ||
9 | #ifndef FIMC_MDEVICE_H_ | |
10 | #define FIMC_MDEVICE_H_ | |
11 | ||
12 | #include <linux/clk.h> | |
d3f5e0c5 | 13 | #include <linux/clk-provider.h> |
d3953223 SN |
14 | #include <linux/platform_device.h> |
15 | #include <linux/mutex.h> | |
e781bbe3 | 16 | #include <linux/of.h> |
4163851f | 17 | #include <linux/pinctrl/consumer.h> |
d3953223 SN |
18 | #include <media/media-device.h> |
19 | #include <media/media-entity.h> | |
20 | #include <media/v4l2-device.h> | |
21 | #include <media/v4l2-subdev.h> | |
d647f0b7 | 22 | #include <media/drv-intf/exynos-fimc.h> |
d3953223 SN |
23 | |
24 | #include "fimc-core.h" | |
4af81310 | 25 | #include "fimc-lite.h" |
d3953223 SN |
26 | #include "mipi-csis.h" |
27 | ||
e2985a26 SN |
28 | #define FIMC_OF_NODE_NAME "fimc" |
29 | #define FIMC_LITE_OF_NODE_NAME "fimc-lite" | |
30 | #define FIMC_IS_OF_NODE_NAME "fimc-is" | |
31 | #define CSIS_OF_NODE_NAME "csis" | |
32 | ||
4163851f SN |
33 | #define PINCTRL_STATE_IDLE "idle" |
34 | ||
fa91f105 | 35 | #define FIMC_MAX_SENSORS 4 |
d3953223 | 36 | #define FIMC_MAX_CAMCLKS 2 |
fa91f105 | 37 | #define DEFAULT_SENSOR_CLK_FREQ 24000000U |
d3953223 | 38 | |
056f4f30 SN |
39 | /* LCD/ISP Writeback clocks (PIXELASYNCMx) */ |
40 | enum { | |
41 | CLK_IDX_WB_A, | |
42 | CLK_IDX_WB_B, | |
43 | FIMC_MAX_WBCLKS | |
44 | }; | |
45 | ||
403dfbec SN |
46 | enum fimc_subdev_index { |
47 | IDX_SENSOR, | |
48 | IDX_CSIS, | |
49 | IDX_FLITE, | |
50 | IDX_IS_ISP, | |
51 | IDX_FIMC, | |
52 | IDX_MAX, | |
53 | }; | |
54 | ||
55 | /* | |
56 | * This structure represents a chain of media entities, including a data | |
57 | * source entity (e.g. an image sensor subdevice), a data capture entity | |
58 | * - a video capture device node and any remaining entities. | |
59 | */ | |
60 | struct fimc_pipeline { | |
61 | struct exynos_media_pipeline ep; | |
62 | struct list_head list; | |
63 | struct media_entity *vdev_entity; | |
64 | struct v4l2_subdev *subdevs[IDX_MAX]; | |
65 | }; | |
66 | ||
67 | #define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep) | |
68 | ||
d3953223 SN |
69 | struct fimc_csis_info { |
70 | struct v4l2_subdev *sd; | |
71 | int id; | |
72 | }; | |
73 | ||
74 | struct fimc_camclk_info { | |
75 | struct clk *clock; | |
76 | int use_count; | |
77 | unsigned long frequency; | |
78 | }; | |
79 | ||
80 | /** | |
81 | * struct fimc_sensor_info - image data source subdev information | |
82 | * @pdata: sensor's atrributes passed as media device's platform data | |
fa91f105 | 83 | * @asd: asynchronous subdev registration data structure |
d3953223 SN |
84 | * @subdev: image sensor v4l2 subdev |
85 | * @host: fimc device the sensor is currently linked to | |
d3953223 SN |
86 | * |
87 | * This data structure applies to image sensor and the writeback subdevs. | |
88 | */ | |
89 | struct fimc_sensor_info { | |
56bc911a | 90 | struct fimc_source_info pdata; |
fa91f105 | 91 | struct v4l2_async_subdev asd; |
d3953223 SN |
92 | struct v4l2_subdev *subdev; |
93 | struct fimc_dev *host; | |
d3953223 SN |
94 | }; |
95 | ||
d3f5e0c5 SN |
96 | struct cam_clk { |
97 | struct clk_hw hw; | |
98 | struct fimc_md *fmd; | |
99 | }; | |
100 | #define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw) | |
101 | ||
d3953223 SN |
102 | /** |
103 | * struct fimc_md - fimc media device information | |
104 | * @csis: MIPI CSIS subdevs data | |
105 | * @sensor: array of registered sensor subdevs | |
106 | * @num_sensors: actual number of registered sensors | |
107 | * @camclk: external sensor clock information | |
108 | * @fimc: array of registered fimc devices | |
e781bbe3 | 109 | * @fimc_is: fimc-is data structure |
056f4f30 | 110 | * @use_isp: set to true when FIMC-IS subsystem is used |
3e20c345 | 111 | * @pmf: handle to the CAMCLK clock control FIMC helper device |
d3953223 SN |
112 | * @media_dev: top level media device |
113 | * @v4l2_dev: top level v4l2_device holding up the subdevs | |
114 | * @pdev: platform device this media device is hooked up into | |
4163851f SN |
115 | * @pinctrl: camera port pinctrl handle |
116 | * @state_default: pinctrl default state handle | |
117 | * @state_idle: pinctrl idle state handle | |
d3f5e0c5 | 118 | * @cam_clk_provider: CAMCLK clock provider structure |
d3953223 SN |
119 | * @user_subdev_api: true if subdevs are not configured by the host driver |
120 | * @slock: spinlock protecting @sensor array | |
121 | */ | |
122 | struct fimc_md { | |
123 | struct fimc_csis_info csis[CSIS_MAX_ENTITIES]; | |
124 | struct fimc_sensor_info sensor[FIMC_MAX_SENSORS]; | |
125 | int num_sensors; | |
126 | struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS]; | |
056f4f30 | 127 | struct clk *wbclk[FIMC_MAX_WBCLKS]; |
4af81310 | 128 | struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS]; |
d3953223 | 129 | struct fimc_dev *fimc[FIMC_MAX_DEVS]; |
e781bbe3 | 130 | struct fimc_is *fimc_is; |
056f4f30 | 131 | bool use_isp; |
3e20c345 | 132 | struct device *pmf; |
d3953223 SN |
133 | struct media_device media_dev; |
134 | struct v4l2_device v4l2_dev; | |
135 | struct platform_device *pdev; | |
d3f5e0c5 | 136 | |
4163851f SN |
137 | struct fimc_pinctrl { |
138 | struct pinctrl *pinctrl; | |
139 | struct pinctrl_state *state_default; | |
140 | struct pinctrl_state *state_idle; | |
141 | } pinctl; | |
403dfbec | 142 | |
d3f5e0c5 SN |
143 | struct cam_clk_provider { |
144 | struct clk *clks[FIMC_MAX_CAMCLKS]; | |
145 | struct clk_onecell_data clk_data; | |
146 | struct device_node *of_node; | |
147 | struct cam_clk camclk[FIMC_MAX_CAMCLKS]; | |
148 | int num_clocks; | |
149 | } clk_provider; | |
150 | ||
fa91f105 SN |
151 | struct v4l2_async_notifier subdev_notifier; |
152 | struct v4l2_async_subdev *async_subdevs[FIMC_MAX_SENSORS]; | |
153 | ||
d3f5e0c5 | 154 | bool user_subdev_api; |
d3953223 | 155 | spinlock_t slock; |
403dfbec | 156 | struct list_head pipelines; |
fd7e5309 | 157 | struct media_entity_graph link_setup_graph; |
d3953223 SN |
158 | }; |
159 | ||
4c8f0629 SN |
160 | static inline |
161 | struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si) | |
162 | { | |
163 | return container_of(si, struct fimc_sensor_info, pdata); | |
164 | } | |
165 | ||
d3953223 SN |
166 | static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me) |
167 | { | |
d10c9894 JMC |
168 | return me->graph_obj.mdev == NULL ? NULL : |
169 | container_of(me->graph_obj.mdev, struct fimc_md, media_dev); | |
d3953223 SN |
170 | } |
171 | ||
fa91f105 SN |
172 | static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n) |
173 | { | |
174 | return container_of(n, struct fimc_md, subdev_notifier); | |
175 | } | |
176 | ||
bc7584b0 | 177 | static inline void fimc_md_graph_lock(struct exynos_video_entity *ve) |
d3953223 | 178 | { |
d10c9894 | 179 | mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); |
d3953223 SN |
180 | } |
181 | ||
bc7584b0 | 182 | static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve) |
d3953223 | 183 | { |
d10c9894 | 184 | mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex); |
d3953223 SN |
185 | } |
186 | ||
187 | int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on); | |
d3953223 | 188 | |
e781bbe3 SN |
189 | #ifdef CONFIG_OF |
190 | static inline bool fimc_md_is_isp_available(struct device_node *node) | |
191 | { | |
192 | node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME); | |
193 | return node ? of_device_is_available(node) : false; | |
194 | } | |
195 | #else | |
196 | #define fimc_md_is_isp_available(node) (false) | |
197 | #endif /* CONFIG_OF */ | |
198 | ||
403dfbec SN |
199 | static inline struct v4l2_subdev *__fimc_md_get_subdev( |
200 | struct exynos_media_pipeline *ep, | |
201 | unsigned int index) | |
202 | { | |
203 | struct fimc_pipeline *p = to_fimc_pipeline(ep); | |
204 | ||
205 | if (!p || index >= IDX_MAX) | |
206 | return NULL; | |
207 | else | |
208 | return p->subdevs[index]; | |
209 | } | |
210 | ||
d3953223 | 211 | #endif |