diff options
author | Bhanu Murthy V <bmurthyv@nvidia.com> | 2016-02-02 18:57:11 -0500 |
---|---|---|
committer | Bhanu Murthy V <bmurthyv@nvidia.com> | 2017-03-22 13:20:02 -0400 |
commit | 6c464e60e6a0ff21a3279f4a5cd986b0bb1bd663 (patch) | |
tree | 77400606102147748dfed3b55e19a66ae4bd1a36 /drivers/media | |
parent | 22a6db6182bbd5b98f7637b16805403a35082ff4 (diff) |
drivers: media: Add device to camera_common
Init device to camera common for drivers
where i2c_client is not available. e.g: csi
Bug 1617777
Bug 1736471
Change-Id: Ic0e1b8e66b971834d51a3928cfe839c50ebfdf04
Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com>
Reviewed-on: http://git-master/r/1002022
(cherry picked from commit 2a7e70ca986005b9384dddc6d4bb241d09f910c9)
Reviewed-on: http://git-master/r/1144970
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/i2c/imx214.c | 1283 | ||||
-rw-r--r-- | drivers/media/i2c/ov23850.c | 1 | ||||
-rw-r--r-- | drivers/media/i2c/ov5693.c | 1 | ||||
-rw-r--r-- | drivers/media/platform/tegra/camera/camera_common.c | 31 |
4 files changed, 1296 insertions, 20 deletions
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c new file mode 100644 index 000000000..6fac95913 --- /dev/null +++ b/drivers/media/i2c/imx214.c | |||
@@ -0,0 +1,1283 @@ | |||
1 | /* | ||
2 | * imx214.c - imx214 sensor driver | ||
3 | * | ||
4 | * Copyright (c) 2013-2016, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #include <linux/slab.h> | ||
20 | #include <linux/uaccess.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/module.h> | ||
23 | |||
24 | #include <linux/seq_file.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/of_gpio.h> | ||
28 | |||
29 | #include <media/camera_common.h> | ||
30 | #include <media/imx214.h> | ||
31 | |||
32 | #include "imx214_mode_tbls.h" | ||
33 | |||
34 | #define IMX214_MAX_COARSE_DIFF 10 | ||
35 | |||
36 | #define IMX214_GAIN_SHIFT 8 | ||
37 | #define IMX214_MIN_GAIN (1 << IMX214_GAIN_SHIFT) | ||
38 | #define IMX214_MAX_GAIN (16 << IMX214_GAIN_SHIFT) | ||
39 | #define IMX214_MIN_FRAME_LENGTH (0x0) | ||
40 | #define IMX214_MAX_FRAME_LENGTH (0xffff) | ||
41 | #define IMX214_MIN_EXPOSURE_COARSE (0x0001) | ||
42 | #define IMX214_MAX_EXPOSURE_COARSE \ | ||
43 | (IMX214_MAX_FRAME_LENGTH-IMX214_MAX_COARSE_DIFF) | ||
44 | |||
45 | #define IMX214_DEFAULT_GAIN IMX214_MIN_GAIN | ||
46 | #define IMX214_DEFAULT_FRAME_LENGTH (0x0C7A) | ||
47 | #define IMX214_DEFAULT_EXPOSURE_COARSE \ | ||
48 | (IMX214_DEFAULT_FRAME_LENGTH-IMX214_MAX_COARSE_DIFF) | ||
49 | |||
50 | #define IMX214_DEFAULT_MODE IMX214_MODE_4096X3072 | ||
51 | #define IMX214_DEFAULT_HDR_MODE IMX214_MODE_4096X3072_HDR | ||
52 | #define IMX214_DEFAULT_WIDTH 4096 | ||
53 | #define IMX214_DEFAULT_HEIGHT 3072 | ||
54 | #define IMX214_DEFAULT_DATAFMT V4L2_MBUS_FMT_SRGGB10_1X10 | ||
55 | #define IMX214_DEFAULT_CLK_FREQ 24000000 | ||
56 | |||
57 | struct imx214 { | ||
58 | struct camera_common_power_rail power; | ||
59 | int numctrls; | ||
60 | struct v4l2_ctrl_handler ctrl_handler; | ||
61 | struct camera_common_eeprom_data eeprom[IMX214_EEPROM_NUM_BLOCKS]; | ||
62 | u8 eeprom_buf[IMX214_EEPROM_SIZE]; | ||
63 | struct i2c_client *i2c_client; | ||
64 | struct v4l2_subdev *subdev; | ||
65 | struct media_pad pad; | ||
66 | |||
67 | s32 group_hold_prev; | ||
68 | bool group_hold_en; | ||
69 | struct regmap *regmap; | ||
70 | struct camera_common_data *s_data; | ||
71 | struct camera_common_pdata *pdata; | ||
72 | struct v4l2_ctrl *ctrls[]; | ||
73 | }; | ||
74 | |||
75 | static const struct regmap_config sensor_regmap_config = { | ||
76 | .reg_bits = 16, | ||
77 | .val_bits = 8, | ||
78 | .cache_type = REGCACHE_RBTREE, | ||
79 | }; | ||
80 | |||
81 | static int imx214_g_volatile_ctrl(struct v4l2_ctrl *ctrl); | ||
82 | static int imx214_s_ctrl(struct v4l2_ctrl *ctrl); | ||
83 | |||
84 | static const struct v4l2_ctrl_ops imx214_ctrl_ops = { | ||
85 | .g_volatile_ctrl = imx214_g_volatile_ctrl, | ||
86 | .s_ctrl = imx214_s_ctrl, | ||
87 | }; | ||
88 | |||
89 | static struct v4l2_ctrl_config ctrl_config_list[] = { | ||
90 | /* Do not change the name field for the controls! */ | ||
91 | { | ||
92 | .ops = &imx214_ctrl_ops, | ||
93 | .id = V4L2_CID_GAIN, | ||
94 | .name = "Gain", | ||
95 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
96 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
97 | .min = IMX214_MIN_GAIN, | ||
98 | .max = IMX214_MAX_GAIN, | ||
99 | .def = IMX214_DEFAULT_GAIN, | ||
100 | .step = 1, | ||
101 | }, | ||
102 | { | ||
103 | .ops = &imx214_ctrl_ops, | ||
104 | .id = V4L2_CID_FRAME_LENGTH, | ||
105 | .name = "Frame Length", | ||
106 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
107 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
108 | .min = IMX214_MIN_FRAME_LENGTH, | ||
109 | .max = IMX214_MAX_FRAME_LENGTH, | ||
110 | .def = IMX214_DEFAULT_FRAME_LENGTH, | ||
111 | .step = 1, | ||
112 | }, | ||
113 | { | ||
114 | .ops = &imx214_ctrl_ops, | ||
115 | .id = V4L2_CID_COARSE_TIME, | ||
116 | .name = "Coarse Time", | ||
117 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
118 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
119 | .min = IMX214_MIN_EXPOSURE_COARSE, | ||
120 | .max = IMX214_MAX_EXPOSURE_COARSE, | ||
121 | .def = IMX214_DEFAULT_EXPOSURE_COARSE, | ||
122 | .step = 1, | ||
123 | }, | ||
124 | { | ||
125 | .ops = &imx214_ctrl_ops, | ||
126 | .id = V4L2_CID_COARSE_TIME_SHORT, | ||
127 | .name = "Coarse Time Short", | ||
128 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
129 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
130 | .min = IMX214_MIN_EXPOSURE_COARSE, | ||
131 | .max = IMX214_MAX_EXPOSURE_COARSE, | ||
132 | .def = IMX214_DEFAULT_EXPOSURE_COARSE, | ||
133 | .step = 1, | ||
134 | }, | ||
135 | { | ||
136 | .ops = &imx214_ctrl_ops, | ||
137 | .id = V4L2_CID_GROUP_HOLD, | ||
138 | .name = "Group Hold", | ||
139 | .type = V4L2_CTRL_TYPE_INTEGER_MENU, | ||
140 | .min = 0, | ||
141 | .max = ARRAY_SIZE(switch_ctrl_qmenu) - 1, | ||
142 | .menu_skip_mask = 0, | ||
143 | .def = 0, | ||
144 | .qmenu_int = switch_ctrl_qmenu, | ||
145 | }, | ||
146 | { | ||
147 | .ops = &imx214_ctrl_ops, | ||
148 | .id = V4L2_CID_HDR_EN, | ||
149 | .name = "HDR enable", | ||
150 | .type = V4L2_CTRL_TYPE_INTEGER_MENU, | ||
151 | .min = 0, | ||
152 | .max = ARRAY_SIZE(switch_ctrl_qmenu) - 1, | ||
153 | .menu_skip_mask = 0, | ||
154 | .def = 0, | ||
155 | .qmenu_int = switch_ctrl_qmenu, | ||
156 | }, | ||
157 | { | ||
158 | .ops = &imx214_ctrl_ops, | ||
159 | .id = V4L2_CID_EEPROM_DATA, | ||
160 | .name = "EEPROM Data", | ||
161 | .type = V4L2_CTRL_TYPE_STRING, | ||
162 | .flags = V4L2_CTRL_FLAG_VOLATILE, | ||
163 | .min = 0, | ||
164 | .max = IMX214_EEPROM_STR_SIZE, | ||
165 | .step = 2, | ||
166 | }, | ||
167 | { | ||
168 | .ops = &imx214_ctrl_ops, | ||
169 | .id = V4L2_CID_OTP_DATA, | ||
170 | .name = "OTP Data", | ||
171 | .type = V4L2_CTRL_TYPE_STRING, | ||
172 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
173 | .min = 0, | ||
174 | .max = IMX214_OTP_STR_SIZE, | ||
175 | .step = 2, | ||
176 | }, | ||
177 | { | ||
178 | .ops = &imx214_ctrl_ops, | ||
179 | .id = V4L2_CID_FUSE_ID, | ||
180 | .name = "Fuse ID", | ||
181 | .type = V4L2_CTRL_TYPE_STRING, | ||
182 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
183 | .min = 0, | ||
184 | .max = IMX214_FUSE_ID_STR_SIZE, | ||
185 | .step = 2, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static inline void imx214_get_frame_length_regs(imx214_reg *regs, | ||
190 | u16 frame_length) | ||
191 | { | ||
192 | regs->addr = IMX214_FRAME_LENGTH_ADDR_MSB; | ||
193 | regs->val = (frame_length >> 8) & 0xff; | ||
194 | (regs + 1)->addr = IMX214_FRAME_LENGTH_ADDR_LSB; | ||
195 | (regs + 1)->val = (frame_length) & 0xff; | ||
196 | } | ||
197 | |||
198 | static inline void imx214_get_coarse_time_regs(imx214_reg *regs, | ||
199 | u16 coarse_time) | ||
200 | { | ||
201 | regs->addr = IMX214_COARSE_TIME_ADDR_MSB; | ||
202 | regs->val = (coarse_time >> 8) & 0xff; | ||
203 | (regs + 1)->addr = IMX214_COARSE_TIME_ADDR_LSB; | ||
204 | (regs + 1)->val = (coarse_time) & 0xff; | ||
205 | } | ||
206 | |||
207 | static inline void imx214_get_coarse_time_short_regs(imx214_reg *regs, | ||
208 | u16 coarse_time) | ||
209 | { | ||
210 | regs->addr = IMX214_COARSE_TIME_SHORT_ADDR_MSB; | ||
211 | regs->val = (coarse_time >> 8) & 0xff; | ||
212 | (regs + 1)->addr = IMX214_COARSE_TIME_SHORT_ADDR_LSB; | ||
213 | (regs + 1)->val = (coarse_time) & 0xff; | ||
214 | } | ||
215 | |||
216 | static inline void imx214_get_gain_regs(imx214_reg *regs, | ||
217 | u16 gain) | ||
218 | { | ||
219 | regs->addr = IMX214_GAIN_ADDR_MSB; | ||
220 | regs->val = (gain >> 8) & 0xff; | ||
221 | (regs + 1)->addr = IMX214_GAIN_ADDR_LSB; | ||
222 | (regs + 1)->val = (gain) & 0xff; | ||
223 | } | ||
224 | |||
225 | static inline void imx214_get_gain_short_reg(imx214_reg *regs, | ||
226 | u16 gain) | ||
227 | { | ||
228 | regs->addr = IMX214_GAIN_SHORT_ADDR_MSB; | ||
229 | regs->val = (gain >> 8) & 0xff; | ||
230 | (regs + 1)->addr = IMX214_GAIN_SHORT_ADDR_LSB; | ||
231 | (regs + 1)->val = (gain) & 0xff; | ||
232 | } | ||
233 | |||
234 | static int test_mode; | ||
235 | module_param(test_mode, int, 0644); | ||
236 | |||
237 | static inline int imx214_read_reg(struct camera_common_data *s_data, | ||
238 | u16 addr, u8 *val) | ||
239 | { | ||
240 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
241 | |||
242 | return regmap_read(priv->regmap, addr, (unsigned int *) val); | ||
243 | } | ||
244 | |||
245 | static int imx214_write_reg(struct camera_common_data *s_data, u16 addr, u8 val) | ||
246 | { | ||
247 | int err; | ||
248 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
249 | |||
250 | err = regmap_write(priv->regmap, addr, val); | ||
251 | if (err) | ||
252 | pr_err("%s:i2c write failed, %x = %x\n", | ||
253 | __func__, addr, val); | ||
254 | |||
255 | return err; | ||
256 | } | ||
257 | |||
258 | static int imx214_write_table(struct imx214 *priv, | ||
259 | const imx214_reg table[]) | ||
260 | { | ||
261 | return regmap_util_write_table_8(priv->regmap, | ||
262 | table, | ||
263 | NULL, 0, | ||
264 | IMX214_TABLE_WAIT_MS, | ||
265 | IMX214_TABLE_END); | ||
266 | } | ||
267 | |||
268 | static int imx214_power_on(struct camera_common_data *s_data) | ||
269 | { | ||
270 | int err = 0; | ||
271 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
272 | struct camera_common_power_rail *pw = &priv->power; | ||
273 | |||
274 | dev_dbg(&priv->i2c_client->dev, "%s: power on\n", __func__); | ||
275 | |||
276 | if (priv->pdata && priv->pdata->power_on) { | ||
277 | err = priv->pdata->power_on(pw); | ||
278 | if (err) | ||
279 | pr_err("%s failed.\n", __func__); | ||
280 | else | ||
281 | pw->state = SWITCH_ON; | ||
282 | return err; | ||
283 | } | ||
284 | |||
285 | /* sleep calls in the sequence below are for internal device | ||
286 | * signal propagation as specified by sensor vendor */ | ||
287 | |||
288 | if (pw->reset_gpio) | ||
289 | gpio_set_value(pw->reset_gpio, 0); | ||
290 | if (pw->af_gpio) | ||
291 | gpio_set_value(pw->af_gpio, 1); | ||
292 | if (pw->pwdn_gpio) | ||
293 | gpio_set_value(pw->pwdn_gpio, 0); | ||
294 | usleep_range(10, 20); | ||
295 | |||
296 | if (pw->avdd) | ||
297 | err = regulator_enable(pw->avdd); | ||
298 | if (err) | ||
299 | goto imx214_avdd_fail; | ||
300 | |||
301 | if (pw->iovdd) | ||
302 | err = regulator_enable(pw->iovdd); | ||
303 | if (err) | ||
304 | goto imx214_iovdd_fail; | ||
305 | |||
306 | udelay(1); | ||
307 | if (pw->reset_gpio) | ||
308 | gpio_set_value(pw->reset_gpio, 1); | ||
309 | if (pw->pwdn_gpio) | ||
310 | gpio_set_value(pw->pwdn_gpio, 1); | ||
311 | |||
312 | usleep_range(300, 310); | ||
313 | |||
314 | pw->state = SWITCH_ON; | ||
315 | return 0; | ||
316 | |||
317 | imx214_iovdd_fail: | ||
318 | regulator_disable(pw->avdd); | ||
319 | |||
320 | imx214_avdd_fail: | ||
321 | if (pw->af_gpio) | ||
322 | gpio_set_value(pw->af_gpio, 0); | ||
323 | |||
324 | pr_err("%s failed.\n", __func__); | ||
325 | return -ENODEV; | ||
326 | } | ||
327 | |||
328 | static int imx214_power_off(struct camera_common_data *s_data) | ||
329 | { | ||
330 | int err = 0; | ||
331 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
332 | struct camera_common_power_rail *pw = &priv->power; | ||
333 | |||
334 | dev_dbg(&priv->i2c_client->dev, "%s: power off\n", __func__); | ||
335 | |||
336 | if (priv->pdata && priv->pdata->power_on) { | ||
337 | err = priv->pdata->power_off(pw); | ||
338 | if (err) { | ||
339 | pr_err("%s failed.\n", __func__); | ||
340 | return err; | ||
341 | } else { | ||
342 | goto power_off_done; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | /* sleeps calls in the sequence below are for internal device | ||
347 | * signal propagation as specified by sensor vendor */ | ||
348 | |||
349 | usleep_range(1, 2); | ||
350 | if (pw->reset_gpio) | ||
351 | gpio_set_value(pw->reset_gpio, 0); | ||
352 | if (pw->af_gpio) | ||
353 | gpio_set_value(pw->af_gpio, 0); | ||
354 | if (pw->pwdn_gpio) | ||
355 | gpio_set_value(pw->pwdn_gpio, 0); | ||
356 | usleep_range(1, 2); | ||
357 | |||
358 | if (pw->iovdd) | ||
359 | regulator_disable(pw->iovdd); | ||
360 | if (pw->avdd) | ||
361 | regulator_disable(pw->avdd); | ||
362 | |||
363 | power_off_done: | ||
364 | pw->state = SWITCH_OFF; | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int imx214_power_put(struct imx214 *priv) | ||
369 | { | ||
370 | struct camera_common_power_rail *pw = &priv->power; | ||
371 | if (unlikely(!pw)) | ||
372 | return -EFAULT; | ||
373 | |||
374 | if (likely(pw->avdd)) | ||
375 | regulator_put(pw->avdd); | ||
376 | |||
377 | if (likely(pw->iovdd)) | ||
378 | regulator_put(pw->iovdd); | ||
379 | |||
380 | if (likely(pw->dvdd)) | ||
381 | regulator_put(pw->dvdd); | ||
382 | |||
383 | pw->avdd = NULL; | ||
384 | pw->iovdd = NULL; | ||
385 | pw->dvdd = NULL; | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static int imx214_power_get(struct imx214 *priv) | ||
391 | { | ||
392 | struct camera_common_power_rail *pw = &priv->power; | ||
393 | struct camera_common_pdata *pdata = priv->pdata; | ||
394 | const char *mclk_name; | ||
395 | int err = 0; | ||
396 | |||
397 | mclk_name = priv->pdata->mclk_name ? | ||
398 | priv->pdata->mclk_name : "cam_mclk1"; | ||
399 | pw->mclk = devm_clk_get(&priv->i2c_client->dev, mclk_name); | ||
400 | if (IS_ERR(pw->mclk)) { | ||
401 | dev_err(&priv->i2c_client->dev, | ||
402 | "unable to get clock %s\n", mclk_name); | ||
403 | return PTR_ERR(pw->mclk); | ||
404 | } | ||
405 | |||
406 | /* analog 2.7v */ | ||
407 | err |= camera_common_regulator_get(priv->i2c_client, | ||
408 | &pw->avdd, pdata->regulators.avdd); | ||
409 | /* digital 1.2v */ | ||
410 | err |= camera_common_regulator_get(priv->i2c_client, | ||
411 | &pw->dvdd, pdata->regulators.dvdd); | ||
412 | /* IO 1.8v */ | ||
413 | err |= camera_common_regulator_get(priv->i2c_client, | ||
414 | &pw->iovdd, pdata->regulators.iovdd); | ||
415 | |||
416 | if (!err) { | ||
417 | pw->reset_gpio = pdata->reset_gpio; | ||
418 | pw->af_gpio = pdata->af_gpio; | ||
419 | pw->pwdn_gpio = pdata->pwdn_gpio; | ||
420 | } | ||
421 | |||
422 | pw->state = SWITCH_OFF; | ||
423 | return err; | ||
424 | } | ||
425 | |||
426 | static int imx214_set_gain(struct imx214 *priv, s32 val); | ||
427 | static int imx214_set_frame_length(struct imx214 *priv, s32 val); | ||
428 | static int imx214_set_coarse_time(struct imx214 *priv, s32 val); | ||
429 | static int imx214_set_coarse_time_short(struct imx214 *priv, s32 val); | ||
430 | |||
431 | static int imx214_s_stream(struct v4l2_subdev *sd, int enable) | ||
432 | { | ||
433 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
434 | struct camera_common_data *s_data = to_camera_common_data(client); | ||
435 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
436 | struct v4l2_control control; | ||
437 | int err; | ||
438 | |||
439 | dev_dbg(&client->dev, "%s++ enable %d\n", __func__, enable); | ||
440 | if (!enable) | ||
441 | return imx214_write_table(priv, | ||
442 | mode_table[IMX214_MODE_STOP_STREAM]); | ||
443 | |||
444 | err = imx214_write_table(priv, mode_table[IMX214_MODE_COMMON]); | ||
445 | if (err) | ||
446 | goto exit; | ||
447 | err = imx214_write_table(priv, mode_table[s_data->mode]); | ||
448 | if (err) | ||
449 | goto exit; | ||
450 | |||
451 | /* write list of override regs for the asking frame length, */ | ||
452 | /* coarse integration time, and gain. Failures to write | ||
453 | * overrides are non-fatal */ | ||
454 | control.id = V4L2_CID_GAIN; | ||
455 | err = v4l2_g_ctrl(&priv->ctrl_handler, &control); | ||
456 | err |= imx214_set_gain(priv, control.value); | ||
457 | if (err) | ||
458 | dev_dbg(&client->dev, "%s: warning gain override failed\n", | ||
459 | __func__); | ||
460 | |||
461 | control.id = V4L2_CID_FRAME_LENGTH; | ||
462 | err = v4l2_g_ctrl(&priv->ctrl_handler, &control); | ||
463 | err |= imx214_set_frame_length(priv, control.value); | ||
464 | if (err) | ||
465 | dev_dbg(&client->dev, | ||
466 | "%s: warning frame length override failed\n", __func__); | ||
467 | |||
468 | control.id = V4L2_CID_COARSE_TIME; | ||
469 | err = v4l2_g_ctrl(&priv->ctrl_handler, &control); | ||
470 | err |= imx214_set_coarse_time(priv, control.value); | ||
471 | if (err) | ||
472 | dev_dbg(&client->dev, | ||
473 | "%s: warning coarse time override failed\n", __func__); | ||
474 | |||
475 | control.id = V4L2_CID_COARSE_TIME_SHORT; | ||
476 | err = v4l2_g_ctrl(&priv->ctrl_handler, &control); | ||
477 | err |= imx214_set_coarse_time_short(priv, control.value); | ||
478 | if (err) | ||
479 | dev_dbg(&client->dev, | ||
480 | "%s: warning coarse time short override failed\n", | ||
481 | __func__); | ||
482 | |||
483 | err = imx214_write_table(priv, mode_table[IMX214_MODE_START_STREAM]); | ||
484 | if (err) | ||
485 | goto exit; | ||
486 | |||
487 | if (test_mode) | ||
488 | err = imx214_write_table(priv, | ||
489 | mode_table[IMX214_MODE_TEST_PATTERN]); | ||
490 | |||
491 | return 0; | ||
492 | exit: | ||
493 | dev_dbg(&client->dev, "%s: error setting stream\n", __func__); | ||
494 | return err; | ||
495 | } | ||
496 | |||
497 | static struct v4l2_subdev_video_ops imx214_subdev_video_ops = { | ||
498 | .s_stream = imx214_s_stream, | ||
499 | .s_mbus_fmt = camera_common_s_fmt, | ||
500 | .g_mbus_fmt = camera_common_g_fmt, | ||
501 | .try_mbus_fmt = camera_common_try_fmt, | ||
502 | .enum_mbus_fmt = camera_common_enum_fmt, | ||
503 | .g_mbus_config = camera_common_g_mbus_config, | ||
504 | }; | ||
505 | |||
506 | static struct v4l2_subdev_core_ops imx214_subdev_core_ops = { | ||
507 | .s_power = camera_common_s_power, | ||
508 | }; | ||
509 | |||
510 | static struct v4l2_subdev_ops imx214_subdev_ops = { | ||
511 | .core = &imx214_subdev_core_ops, | ||
512 | .video = &imx214_subdev_video_ops, | ||
513 | }; | ||
514 | |||
515 | static struct of_device_id imx214_of_match[] = { | ||
516 | { .compatible = "nvidia,imx214", }, | ||
517 | { }, | ||
518 | }; | ||
519 | |||
520 | static struct camera_common_sensor_ops imx214_common_ops = { | ||
521 | .power_on = imx214_power_on, | ||
522 | .power_off = imx214_power_off, | ||
523 | .write_reg = imx214_write_reg, | ||
524 | .read_reg = imx214_read_reg, | ||
525 | }; | ||
526 | |||
527 | static int imx214_set_group_hold(struct imx214 *priv) | ||
528 | { | ||
529 | int err; | ||
530 | int gh_prev = switch_ctrl_qmenu[priv->group_hold_prev]; | ||
531 | |||
532 | if (priv->group_hold_en == true && gh_prev == SWITCH_OFF) { | ||
533 | err = imx214_write_reg(priv->s_data, | ||
534 | IMX214_GROUP_HOLD_ADDR, 0x1); | ||
535 | if (err) | ||
536 | goto fail; | ||
537 | priv->group_hold_prev = 1; | ||
538 | } else if (priv->group_hold_en == false && gh_prev == SWITCH_ON) { | ||
539 | err = imx214_write_reg(priv->s_data, | ||
540 | IMX214_GROUP_HOLD_ADDR, 0x0); | ||
541 | if (err) | ||
542 | goto fail; | ||
543 | priv->group_hold_prev = 0; | ||
544 | } | ||
545 | |||
546 | return 0; | ||
547 | |||
548 | fail: | ||
549 | dev_dbg(&priv->i2c_client->dev, | ||
550 | "%s: Group hold control error\n", __func__); | ||
551 | return err; | ||
552 | } | ||
553 | |||
554 | static int imx214_calculate_gain(u32 rep, int shift) | ||
555 | { | ||
556 | int gain; | ||
557 | int gain_int; | ||
558 | int gain_dec; | ||
559 | int min_int = (1 << shift); | ||
560 | int denom; | ||
561 | |||
562 | /* shift indicates number of least significant bits | ||
563 | * used for decimal representation of gain */ | ||
564 | gain_int = (int)(rep >> shift); | ||
565 | gain_dec = (int)(rep & ~(0xffff << shift)); | ||
566 | |||
567 | denom = gain_int * min_int + gain_dec; | ||
568 | gain = 512 - ((512 * min_int + (denom - 1)) / denom); | ||
569 | |||
570 | return gain; | ||
571 | } | ||
572 | |||
573 | static int imx214_set_gain(struct imx214 *priv, s32 val) | ||
574 | { | ||
575 | imx214_reg reg_list[2]; | ||
576 | imx214_reg reg_list_short[2]; | ||
577 | int err; | ||
578 | u16 gain; | ||
579 | int i = 0; | ||
580 | |||
581 | /* translate value */ | ||
582 | gain = (u16)imx214_calculate_gain(val, IMX214_GAIN_SHIFT); | ||
583 | |||
584 | dev_dbg(&priv->i2c_client->dev, | ||
585 | "%s: val: %d\n", __func__, gain); | ||
586 | |||
587 | imx214_get_gain_regs(reg_list, gain); | ||
588 | imx214_get_gain_short_reg(reg_list_short, gain); | ||
589 | imx214_set_group_hold(priv); | ||
590 | |||
591 | /* writing long gain */ | ||
592 | for (i = 0; i < 2; i++) { | ||
593 | err = imx214_write_reg(priv->s_data, reg_list[i].addr, | ||
594 | reg_list[i].val); | ||
595 | if (err) | ||
596 | goto fail; | ||
597 | } | ||
598 | /* writing short gain */ | ||
599 | for (i = 0; i < 2; i++) { | ||
600 | err = imx214_write_reg(priv->s_data, reg_list_short[i].addr, | ||
601 | reg_list_short[i].val); | ||
602 | if (err) | ||
603 | goto fail; | ||
604 | } | ||
605 | |||
606 | return 0; | ||
607 | |||
608 | fail: | ||
609 | dev_dbg(&priv->i2c_client->dev, | ||
610 | "%s: GAIN control error\n", __func__); | ||
611 | return err; | ||
612 | } | ||
613 | |||
614 | static int imx214_set_frame_length(struct imx214 *priv, s32 val) | ||
615 | { | ||
616 | imx214_reg reg_list[2]; | ||
617 | int err; | ||
618 | u16 frame_length; | ||
619 | int i = 0; | ||
620 | |||
621 | frame_length = (u16)val; | ||
622 | |||
623 | dev_dbg(&priv->i2c_client->dev, | ||
624 | "%s: val: %d\n", __func__, frame_length); | ||
625 | |||
626 | imx214_get_frame_length_regs(reg_list, frame_length); | ||
627 | imx214_set_group_hold(priv); | ||
628 | |||
629 | for (i = 0; i < 2; i++) { | ||
630 | err = imx214_write_reg(priv->s_data, reg_list[i].addr, | ||
631 | reg_list[i].val); | ||
632 | if (err) | ||
633 | goto fail; | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | |||
638 | fail: | ||
639 | dev_dbg(&priv->i2c_client->dev, | ||
640 | "%s: FRAME_LENGTH control error\n", __func__); | ||
641 | return err; | ||
642 | } | ||
643 | |||
644 | static int imx214_set_coarse_time(struct imx214 *priv, s32 val) | ||
645 | { | ||
646 | imx214_reg reg_list[2]; | ||
647 | int err; | ||
648 | u16 coarse_time; | ||
649 | int i = 0; | ||
650 | |||
651 | coarse_time = (u16)val; | ||
652 | |||
653 | dev_dbg(&priv->i2c_client->dev, | ||
654 | "%s: val: %d\n", __func__, coarse_time); | ||
655 | |||
656 | imx214_get_coarse_time_regs(reg_list, coarse_time); | ||
657 | imx214_set_group_hold(priv); | ||
658 | |||
659 | for (i = 0; i < 2; i++) { | ||
660 | err = imx214_write_reg(priv->s_data, reg_list[i].addr, | ||
661 | reg_list[i].val); | ||
662 | if (err) | ||
663 | goto fail; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | |||
668 | fail: | ||
669 | dev_dbg(&priv->i2c_client->dev, | ||
670 | "%s: COARSE_TIME control error\n", __func__); | ||
671 | return err; | ||
672 | } | ||
673 | |||
674 | static int imx214_set_coarse_time_short(struct imx214 *priv, s32 val) | ||
675 | { | ||
676 | imx214_reg reg_list[2]; | ||
677 | int err; | ||
678 | struct v4l2_control hdr_control; | ||
679 | int hdr_en; | ||
680 | u16 coarse_time_short; | ||
681 | int i = 0; | ||
682 | |||
683 | /* check hdr enable ctrl */ | ||
684 | hdr_control.id = V4L2_CID_HDR_EN; | ||
685 | |||
686 | err = camera_common_g_ctrl(priv->s_data, &hdr_control); | ||
687 | if (err < 0) { | ||
688 | dev_err(&priv->i2c_client->dev, | ||
689 | "could not find device ctrl.\n"); | ||
690 | return err; | ||
691 | } | ||
692 | |||
693 | hdr_en = switch_ctrl_qmenu[hdr_control.value]; | ||
694 | if (hdr_en == SWITCH_OFF) | ||
695 | return 0; | ||
696 | |||
697 | coarse_time_short = (u16)val; | ||
698 | |||
699 | dev_dbg(&priv->i2c_client->dev, | ||
700 | "%s: val: %d\n", __func__, coarse_time_short); | ||
701 | |||
702 | imx214_get_coarse_time_short_regs(reg_list, coarse_time_short); | ||
703 | imx214_set_group_hold(priv); | ||
704 | |||
705 | for (i = 0; i < 2; i++) { | ||
706 | err = imx214_write_reg(priv->s_data, reg_list[i].addr, | ||
707 | reg_list[i].val); | ||
708 | if (err) | ||
709 | goto fail; | ||
710 | } | ||
711 | |||
712 | return 0; | ||
713 | |||
714 | fail: | ||
715 | dev_dbg(&priv->i2c_client->dev, | ||
716 | "%s: COARSE_TIME_SHORT control error\n", __func__); | ||
717 | return err; | ||
718 | } | ||
719 | |||
720 | static int imx214_eeprom_device_release(struct imx214 *priv) | ||
721 | { | ||
722 | int i; | ||
723 | |||
724 | for (i = 0; i < IMX214_EEPROM_NUM_BLOCKS; i++) { | ||
725 | if (priv->eeprom[i].i2c_client != NULL) { | ||
726 | i2c_unregister_device(priv->eeprom[i].i2c_client); | ||
727 | priv->eeprom[i].i2c_client = NULL; | ||
728 | } | ||
729 | } | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static int imx214_eeprom_device_init(struct imx214 *priv) | ||
735 | { | ||
736 | char *dev_name = "eeprom_imx214"; | ||
737 | static struct regmap_config eeprom_regmap_config = { | ||
738 | .reg_bits = 8, | ||
739 | .val_bits = 8, | ||
740 | }; | ||
741 | int i; | ||
742 | int err; | ||
743 | struct v4l2_ctrl *ctrl; | ||
744 | |||
745 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_EEPROM_DATA); | ||
746 | if (!ctrl) { | ||
747 | dev_err(&priv->i2c_client->dev, | ||
748 | "could not find device ctrl.\n"); | ||
749 | return -EINVAL; | ||
750 | } | ||
751 | |||
752 | for (i = 0; i < IMX214_EEPROM_NUM_BLOCKS; i++) { | ||
753 | priv->eeprom[i].adap = i2c_get_adapter( | ||
754 | priv->i2c_client->adapter->nr); | ||
755 | memset(&priv->eeprom[i].brd, 0, sizeof(priv->eeprom[i].brd)); | ||
756 | strncpy(priv->eeprom[i].brd.type, dev_name, | ||
757 | sizeof(priv->eeprom[i].brd.type)); | ||
758 | priv->eeprom[i].brd.addr = IMX214_EEPROM_ADDRESS + i; | ||
759 | priv->eeprom[i].i2c_client = i2c_new_device( | ||
760 | priv->eeprom[i].adap, &priv->eeprom[i].brd); | ||
761 | |||
762 | priv->eeprom[i].regmap = devm_regmap_init_i2c( | ||
763 | priv->eeprom[i].i2c_client, &eeprom_regmap_config); | ||
764 | if (IS_ERR(priv->eeprom[i].regmap)) { | ||
765 | err = PTR_ERR(priv->eeprom[i].regmap); | ||
766 | imx214_eeprom_device_release(priv); | ||
767 | ctrl->flags = V4L2_CTRL_FLAG_DISABLED; | ||
768 | return err; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static int imx214_read_eeprom(struct imx214 *priv, | ||
776 | struct v4l2_ctrl *ctrl) | ||
777 | { | ||
778 | int err, i; | ||
779 | |||
780 | for (i = 0; i < IMX214_EEPROM_NUM_BLOCKS; i++) { | ||
781 | err = regmap_bulk_read(priv->eeprom[i].regmap, 0, | ||
782 | &priv->eeprom_buf[i * IMX214_EEPROM_BLOCK_SIZE], | ||
783 | IMX214_EEPROM_BLOCK_SIZE); | ||
784 | if (err) | ||
785 | return err; | ||
786 | } | ||
787 | |||
788 | for (i = 0; i < IMX214_EEPROM_SIZE; i++) | ||
789 | sprintf(&ctrl->string[i*2], "%02x", | ||
790 | priv->eeprom_buf[i]); | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static int imx214_write_eeprom(struct imx214 *priv, | ||
795 | char *string) | ||
796 | { | ||
797 | int err; | ||
798 | int i; | ||
799 | u8 curr[3]; | ||
800 | unsigned long data; | ||
801 | |||
802 | for (i = 0; i < IMX214_EEPROM_SIZE; i++) { | ||
803 | curr[0] = string[i*2]; | ||
804 | curr[1] = string[i*2+1]; | ||
805 | curr[2] = '\0'; | ||
806 | |||
807 | err = kstrtol(curr, 16, &data); | ||
808 | if (err) { | ||
809 | dev_err(&priv->i2c_client->dev, | ||
810 | "invalid eeprom string\n"); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | |||
814 | priv->eeprom_buf[i] = (u8)data; | ||
815 | err = regmap_write(priv->eeprom[i >> 8].regmap, | ||
816 | i & 0xFF, (u8)data); | ||
817 | if (err) | ||
818 | return err; | ||
819 | msleep(20); | ||
820 | } | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | static int imx214_read_otp_page(struct imx214 *priv, | ||
825 | u8 *buf, int page, u16 addr, int size) | ||
826 | { | ||
827 | u8 status; | ||
828 | int err; | ||
829 | |||
830 | err = imx214_write_reg(priv->s_data, IMX214_OTP_PAGE_NUM_ADDR, page); | ||
831 | if (err) | ||
832 | return err; | ||
833 | err = imx214_write_reg(priv->s_data, IMX214_OTP_CTRL_ADDR, 0x01); | ||
834 | if (err) | ||
835 | return err; | ||
836 | err = imx214_read_reg(priv->s_data, IMX214_OTP_STATUS_ADDR, &status); | ||
837 | if (err) | ||
838 | return err; | ||
839 | if (status == IMX214_OTP_STATUS_IN_PROGRESS) { | ||
840 | dev_err(&priv->i2c_client->dev, | ||
841 | "another OTP read in progress\n"); | ||
842 | return err; | ||
843 | } | ||
844 | |||
845 | err = regmap_bulk_read(priv->regmap, addr, buf, size); | ||
846 | if (err) | ||
847 | return err; | ||
848 | |||
849 | err = imx214_read_reg(priv->s_data, IMX214_OTP_STATUS_ADDR, &status); | ||
850 | if (err) | ||
851 | return err; | ||
852 | if (status == IMX214_OTP_STATUS_READ_FAIL) { | ||
853 | dev_err(&priv->i2c_client->dev, "fuse id read error\n"); | ||
854 | return err; | ||
855 | } | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static int imx214_otp_setup(struct imx214 *priv) | ||
861 | { | ||
862 | int err; | ||
863 | int i; | ||
864 | struct v4l2_ctrl *ctrl; | ||
865 | u8 otp_buf[IMX214_OTP_SIZE]; | ||
866 | |||
867 | err = camera_common_s_power(priv->subdev, true); | ||
868 | if (err) | ||
869 | return -ENODEV; | ||
870 | |||
871 | for (i = 0; i < IMX214_OTP_NUM_PAGES; i++) { | ||
872 | imx214_read_otp_page(priv, | ||
873 | &otp_buf[i * IMX214_OTP_PAGE_SIZE], | ||
874 | i, | ||
875 | IMX214_OTP_PAGE_START_ADDR, | ||
876 | IMX214_OTP_PAGE_SIZE); | ||
877 | } | ||
878 | |||
879 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_OTP_DATA); | ||
880 | if (!ctrl) { | ||
881 | dev_err(&priv->i2c_client->dev, | ||
882 | "could not find device ctrl.\n"); | ||
883 | return -EINVAL; | ||
884 | } | ||
885 | |||
886 | for (i = 0; i < IMX214_OTP_SIZE; i++) | ||
887 | sprintf(&ctrl->string[i*2], "%02x", | ||
888 | otp_buf[i]); | ||
889 | ctrl->cur.string = ctrl->string; | ||
890 | |||
891 | err = camera_common_s_power(priv->subdev, false); | ||
892 | if (err) | ||
893 | return -ENODEV; | ||
894 | |||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | static int imx214_fuse_id_setup(struct imx214 *priv) | ||
899 | { | ||
900 | int err; | ||
901 | int i; | ||
902 | struct v4l2_ctrl *ctrl; | ||
903 | u8 fuse_id[IMX214_FUSE_ID_SIZE]; | ||
904 | |||
905 | err = camera_common_s_power(priv->subdev, true); | ||
906 | if (err) | ||
907 | return -ENODEV; | ||
908 | |||
909 | imx214_read_otp_page(priv, | ||
910 | &fuse_id[0], | ||
911 | IMX214_FUSE_ID_OTP_PAGE, | ||
912 | IMX214_FUSE_ID_OTP_ROW_ADDR, | ||
913 | IMX214_FUSE_ID_SIZE); | ||
914 | |||
915 | ctrl = v4l2_ctrl_find(&priv->ctrl_handler, V4L2_CID_FUSE_ID); | ||
916 | if (!ctrl) { | ||
917 | dev_err(&priv->i2c_client->dev, | ||
918 | "could not find device ctrl.\n"); | ||
919 | return -EINVAL; | ||
920 | } | ||
921 | |||
922 | for (i = 0; i < IMX214_FUSE_ID_SIZE; i++) | ||
923 | sprintf(&ctrl->string[i*2], "%02x", | ||
924 | fuse_id[i]); | ||
925 | ctrl->cur.string = ctrl->string; | ||
926 | |||
927 | err = camera_common_s_power(priv->subdev, false); | ||
928 | if (err) | ||
929 | return -ENODEV; | ||
930 | |||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | static int imx214_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
935 | { | ||
936 | struct imx214 *priv = | ||
937 | container_of(ctrl->handler, struct imx214, ctrl_handler); | ||
938 | int err = 0; | ||
939 | |||
940 | if (priv->power.state == SWITCH_OFF) | ||
941 | return 0; | ||
942 | |||
943 | switch (ctrl->id) { | ||
944 | case V4L2_CID_EEPROM_DATA: | ||
945 | err = imx214_read_eeprom(priv, ctrl); | ||
946 | if (err) | ||
947 | return err; | ||
948 | break; | ||
949 | default: | ||
950 | pr_err("%s: unknown ctrl id.\n", __func__); | ||
951 | return -EINVAL; | ||
952 | } | ||
953 | |||
954 | return err; | ||
955 | } | ||
956 | |||
957 | static int imx214_s_ctrl(struct v4l2_ctrl *ctrl) | ||
958 | { | ||
959 | struct imx214 *priv = | ||
960 | container_of(ctrl->handler, struct imx214, ctrl_handler); | ||
961 | int err = 0; | ||
962 | |||
963 | if (priv->power.state == SWITCH_OFF) | ||
964 | return 0; | ||
965 | |||
966 | switch (ctrl->id) { | ||
967 | case V4L2_CID_GAIN: | ||
968 | err = imx214_set_gain(priv, ctrl->val); | ||
969 | break; | ||
970 | case V4L2_CID_FRAME_LENGTH: | ||
971 | err = imx214_set_frame_length(priv, ctrl->val); | ||
972 | break; | ||
973 | case V4L2_CID_COARSE_TIME: | ||
974 | err = imx214_set_coarse_time(priv, ctrl->val); | ||
975 | break; | ||
976 | case V4L2_CID_COARSE_TIME_SHORT: | ||
977 | err = imx214_set_coarse_time_short(priv, ctrl->val); | ||
978 | break; | ||
979 | case V4L2_CID_GROUP_HOLD: | ||
980 | if (switch_ctrl_qmenu[ctrl->val] == SWITCH_ON) { | ||
981 | priv->group_hold_en = true; | ||
982 | } else { | ||
983 | priv->group_hold_en = false; | ||
984 | err = imx214_set_group_hold(priv); | ||
985 | } | ||
986 | break; | ||
987 | case V4L2_CID_EEPROM_DATA: | ||
988 | if (!ctrl->string[0]) | ||
989 | break; | ||
990 | err = imx214_write_eeprom(priv, ctrl->string); | ||
991 | if (err) | ||
992 | return err; | ||
993 | break; | ||
994 | case V4L2_CID_HDR_EN: | ||
995 | break; | ||
996 | default: | ||
997 | pr_err("%s: unknown ctrl id.\n", __func__); | ||
998 | return -EINVAL; | ||
999 | } | ||
1000 | |||
1001 | return err; | ||
1002 | } | ||
1003 | |||
1004 | static int imx214_ctrls_init(struct imx214 *priv) | ||
1005 | { | ||
1006 | struct i2c_client *client = priv->i2c_client; | ||
1007 | struct v4l2_ctrl *ctrl; | ||
1008 | int numctrls; | ||
1009 | int err; | ||
1010 | int i; | ||
1011 | |||
1012 | dev_dbg(&client->dev, "%s++\n", __func__); | ||
1013 | |||
1014 | numctrls = ARRAY_SIZE(ctrl_config_list); | ||
1015 | v4l2_ctrl_handler_init(&priv->ctrl_handler, numctrls); | ||
1016 | |||
1017 | for (i = 0; i < numctrls; i++) { | ||
1018 | ctrl = v4l2_ctrl_new_custom(&priv->ctrl_handler, | ||
1019 | &ctrl_config_list[i], NULL); | ||
1020 | if (ctrl == NULL) { | ||
1021 | dev_err(&client->dev, "Failed to init %s ctrl\n", | ||
1022 | ctrl_config_list[i].name); | ||
1023 | continue; | ||
1024 | } | ||
1025 | |||
1026 | if (ctrl_config_list[i].type == V4L2_CTRL_TYPE_STRING && | ||
1027 | ctrl_config_list[i].flags & V4L2_CTRL_FLAG_READ_ONLY) { | ||
1028 | ctrl->string = devm_kzalloc(&client->dev, | ||
1029 | ctrl_config_list[i].max + 1, GFP_KERNEL); | ||
1030 | if (!ctrl->string) { | ||
1031 | dev_err(&client->dev, | ||
1032 | "Failed to allocate otp data\n"); | ||
1033 | return -ENOMEM; | ||
1034 | } | ||
1035 | } | ||
1036 | priv->ctrls[i] = ctrl; | ||
1037 | } | ||
1038 | |||
1039 | priv->numctrls = numctrls; | ||
1040 | priv->subdev->ctrl_handler = &priv->ctrl_handler; | ||
1041 | if (priv->ctrl_handler.error) { | ||
1042 | dev_err(&client->dev, "Error %d adding controls\n", | ||
1043 | priv->ctrl_handler.error); | ||
1044 | err = priv->ctrl_handler.error; | ||
1045 | goto error; | ||
1046 | } | ||
1047 | |||
1048 | err = v4l2_ctrl_handler_setup(&priv->ctrl_handler); | ||
1049 | if (err) { | ||
1050 | dev_err(&client->dev, | ||
1051 | "Error %d setting default controls\n", err); | ||
1052 | goto error; | ||
1053 | } | ||
1054 | |||
1055 | err = imx214_otp_setup(priv); | ||
1056 | if (err) { | ||
1057 | dev_err(&client->dev, | ||
1058 | "Error %d reading otp data\n", err); | ||
1059 | goto error; | ||
1060 | } | ||
1061 | |||
1062 | err = imx214_fuse_id_setup(priv); | ||
1063 | if (err) { | ||
1064 | dev_err(&client->dev, | ||
1065 | "Error %d reading fuse id data\n", err); | ||
1066 | goto error; | ||
1067 | } | ||
1068 | |||
1069 | return 0; | ||
1070 | |||
1071 | error: | ||
1072 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | ||
1073 | return err; | ||
1074 | } | ||
1075 | |||
1076 | MODULE_DEVICE_TABLE(of, imx214_of_match); | ||
1077 | |||
1078 | static struct camera_common_pdata *imx214_parse_dt(struct i2c_client *client) | ||
1079 | { | ||
1080 | struct device_node *np = client->dev.of_node; | ||
1081 | struct camera_common_pdata *board_priv_pdata; | ||
1082 | const struct of_device_id *match; | ||
1083 | |||
1084 | match = of_match_device(imx214_of_match, &client->dev); | ||
1085 | if (!match) { | ||
1086 | dev_err(&client->dev, "Failed to find matching dt id\n"); | ||
1087 | return NULL; | ||
1088 | } | ||
1089 | |||
1090 | board_priv_pdata = devm_kzalloc(&client->dev, | ||
1091 | sizeof(*board_priv_pdata), GFP_KERNEL); | ||
1092 | if (!board_priv_pdata) { | ||
1093 | dev_err(&client->dev, "Failed to allocate pdata\n"); | ||
1094 | return NULL; | ||
1095 | } | ||
1096 | |||
1097 | of_property_read_string(np, "mclk", &board_priv_pdata->mclk_name); | ||
1098 | board_priv_pdata->pwdn_gpio = of_get_named_gpio(np, "pwdn-gpios", 0); | ||
1099 | board_priv_pdata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); | ||
1100 | board_priv_pdata->af_gpio = of_get_named_gpio(np, "af-gpios", 0); | ||
1101 | |||
1102 | of_property_read_string(np, "avdd-reg", | ||
1103 | &board_priv_pdata->regulators.avdd); | ||
1104 | of_property_read_string(np, "dvdd-reg", | ||
1105 | &board_priv_pdata->regulators.dvdd); | ||
1106 | of_property_read_string(np, "iovdd-reg", | ||
1107 | &board_priv_pdata->regulators.iovdd); | ||
1108 | |||
1109 | return board_priv_pdata; | ||
1110 | } | ||
1111 | |||
1112 | static int imx214_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
1113 | { | ||
1114 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1115 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
1116 | |||
1117 | |||
1118 | return 0; | ||
1119 | } | ||
1120 | |||
1121 | static const struct v4l2_subdev_internal_ops imx214_subdev_internal_ops = { | ||
1122 | .open = imx214_open, | ||
1123 | }; | ||
1124 | |||
1125 | static const struct media_entity_operations imx214_media_ops = { | ||
1126 | .link_validate = v4l2_subdev_link_validate, | ||
1127 | }; | ||
1128 | |||
1129 | static int imx214_probe(struct i2c_client *client, | ||
1130 | const struct i2c_device_id *id) | ||
1131 | { | ||
1132 | struct camera_common_data *common_data; | ||
1133 | struct device_node *node = client->dev.of_node; | ||
1134 | struct imx214 *priv; | ||
1135 | char debugfs_name[10]; | ||
1136 | int err; | ||
1137 | |||
1138 | pr_info("[IMX214]: probing v4l2 sensor.\n"); | ||
1139 | |||
1140 | if (!IS_ENABLED(CONFIG_OF) || !node) | ||
1141 | return -EINVAL; | ||
1142 | |||
1143 | common_data = devm_kzalloc(&client->dev, | ||
1144 | sizeof(struct camera_common_data), GFP_KERNEL); | ||
1145 | if (!common_data) { | ||
1146 | dev_err(&client->dev, "unable to allocate memory!\n"); | ||
1147 | return -ENOMEM; | ||
1148 | } | ||
1149 | |||
1150 | priv = devm_kzalloc(&client->dev, | ||
1151 | sizeof(struct imx214) + sizeof(struct v4l2_ctrl *) * | ||
1152 | ARRAY_SIZE(ctrl_config_list), | ||
1153 | GFP_KERNEL); | ||
1154 | if (!priv) { | ||
1155 | dev_err(&client->dev, "unable to allocate memory!\n"); | ||
1156 | return -ENOMEM; | ||
1157 | } | ||
1158 | |||
1159 | priv->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config); | ||
1160 | if (IS_ERR(priv->regmap)) { | ||
1161 | dev_err(&client->dev, | ||
1162 | "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); | ||
1163 | return -ENODEV; | ||
1164 | } | ||
1165 | |||
1166 | priv->pdata = imx214_parse_dt(client); | ||
1167 | if (!priv->pdata) { | ||
1168 | dev_err(&client->dev, "unable to get platform data\n"); | ||
1169 | return -EFAULT; | ||
1170 | } | ||
1171 | |||
1172 | common_data->ops = &imx214_common_ops; | ||
1173 | common_data->ctrl_handler = &priv->ctrl_handler; | ||
1174 | common_data->i2c_client = client; | ||
1175 | common_data->frmfmt = &imx214_frmfmt[0]; | ||
1176 | common_data->colorfmt = camera_common_find_datafmt( | ||
1177 | IMX214_DEFAULT_DATAFMT); | ||
1178 | common_data->ctrls = priv->ctrls; | ||
1179 | common_data->power = &priv->power; | ||
1180 | common_data->priv = (void *)priv; | ||
1181 | common_data->numctrls = ARRAY_SIZE(ctrl_config_list); | ||
1182 | common_data->numfmts = ARRAY_SIZE(imx214_frmfmt); | ||
1183 | common_data->def_mode = IMX214_DEFAULT_MODE; | ||
1184 | common_data->def_width = IMX214_DEFAULT_WIDTH; | ||
1185 | common_data->def_height = IMX214_DEFAULT_HEIGHT; | ||
1186 | common_data->def_clk_freq = IMX214_DEFAULT_CLK_FREQ; | ||
1187 | |||
1188 | priv->i2c_client = client; | ||
1189 | priv->s_data = common_data; | ||
1190 | priv->subdev = &common_data->subdev; | ||
1191 | priv->subdev->dev = &client->dev; | ||
1192 | priv->s_data->dev = &client->dev; | ||
1193 | |||
1194 | err = imx214_power_get(priv); | ||
1195 | if (err) | ||
1196 | return err; | ||
1197 | |||
1198 | err = camera_common_parse_ports(client, common_data); | ||
1199 | if (err) { | ||
1200 | dev_err(&client->dev, "Failed to find port info\n"); | ||
1201 | return err; | ||
1202 | } | ||
1203 | sprintf(debugfs_name, "imx214_%c", common_data->csi_port + 'a'); | ||
1204 | dev_dbg(&client->dev, "%s: name %s\n", __func__, debugfs_name); | ||
1205 | camera_common_create_debugfs(common_data, debugfs_name); | ||
1206 | |||
1207 | v4l2_i2c_subdev_init(priv->subdev, client, &imx214_subdev_ops); | ||
1208 | |||
1209 | err = imx214_ctrls_init(priv); | ||
1210 | if (err) | ||
1211 | return err; | ||
1212 | |||
1213 | /* eeprom interface */ | ||
1214 | err = imx214_eeprom_device_init(priv); | ||
1215 | if (err) | ||
1216 | dev_err(&client->dev, | ||
1217 | "Failed to allocate eeprom register map: %d\n", err); | ||
1218 | |||
1219 | priv->subdev->internal_ops = &imx214_subdev_internal_ops; | ||
1220 | priv->subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | | ||
1221 | V4L2_SUBDEV_FL_HAS_EVENTS; | ||
1222 | |||
1223 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1224 | priv->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
1225 | priv->subdev->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; | ||
1226 | priv->subdev->entity.ops = &imx214_media_ops; | ||
1227 | err = media_entity_init(&priv->subdev->entity, 1, &priv->pad, 0); | ||
1228 | if (err < 0) { | ||
1229 | dev_err(&client->dev, "unable to init media entity\n"); | ||
1230 | return err; | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1234 | err = v4l2_async_register_subdev(priv->subdev); | ||
1235 | if (err) | ||
1236 | return err; | ||
1237 | |||
1238 | dev_dbg(&client->dev, "Detected IMX214 sensor\n"); | ||
1239 | |||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | static int | ||
1244 | imx214_remove(struct i2c_client *client) | ||
1245 | { | ||
1246 | struct camera_common_data *s_data = to_camera_common_data(client); | ||
1247 | struct imx214 *priv = (struct imx214 *)s_data->priv; | ||
1248 | |||
1249 | v4l2_async_unregister_subdev(priv->subdev); | ||
1250 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
1251 | media_entity_cleanup(&priv->subdev->entity); | ||
1252 | #endif | ||
1253 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | ||
1254 | imx214_power_put(priv); | ||
1255 | camera_common_remove_debugfs(s_data); | ||
1256 | |||
1257 | return 0; | ||
1258 | } | ||
1259 | |||
1260 | static const struct i2c_device_id imx214_id[] = { | ||
1261 | { "imx214", 0 }, | ||
1262 | { } | ||
1263 | }; | ||
1264 | |||
1265 | MODULE_DEVICE_TABLE(i2c, imx214_id); | ||
1266 | |||
1267 | static struct i2c_driver imx214_i2c_driver = { | ||
1268 | .driver = { | ||
1269 | .name = "imx214", | ||
1270 | .owner = THIS_MODULE, | ||
1271 | .of_match_table = of_match_ptr(imx214_of_match), | ||
1272 | }, | ||
1273 | .probe = imx214_probe, | ||
1274 | .remove = imx214_remove, | ||
1275 | .id_table = imx214_id, | ||
1276 | }; | ||
1277 | |||
1278 | module_i2c_driver(imx214_i2c_driver); | ||
1279 | |||
1280 | MODULE_DESCRIPTION("SoC Camera driver for Sony IMX214"); | ||
1281 | MODULE_AUTHOR("David Wang <davidw@nvidia.com>"); | ||
1282 | MODULE_LICENSE("GPL v2"); | ||
1283 | |||
diff --git a/drivers/media/i2c/ov23850.c b/drivers/media/i2c/ov23850.c index 203888700..0c3768c4f 100644 --- a/drivers/media/i2c/ov23850.c +++ b/drivers/media/i2c/ov23850.c | |||
@@ -1328,6 +1328,7 @@ static int ov23850_probe(struct i2c_client *client, | |||
1328 | priv->s_data = common_data; | 1328 | priv->s_data = common_data; |
1329 | priv->subdev = &common_data->subdev; | 1329 | priv->subdev = &common_data->subdev; |
1330 | priv->subdev->dev = &client->dev; | 1330 | priv->subdev->dev = &client->dev; |
1331 | priv->s_data->dev = &client->dev; | ||
1331 | priv->group_hold_prev = 0; | 1332 | priv->group_hold_prev = 0; |
1332 | 1333 | ||
1333 | err = ov23850_power_get(priv); | 1334 | err = ov23850_power_get(priv); |
diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index 018b81fdf..4d29df801 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c | |||
@@ -1325,6 +1325,7 @@ static int ov5693_probe(struct i2c_client *client, | |||
1325 | priv->s_data = common_data; | 1325 | priv->s_data = common_data; |
1326 | priv->subdev = &common_data->subdev; | 1326 | priv->subdev = &common_data->subdev; |
1327 | priv->subdev->dev = &client->dev; | 1327 | priv->subdev->dev = &client->dev; |
1328 | priv->s_data->dev = &client->dev; | ||
1328 | 1329 | ||
1329 | err = ov5693_power_get(priv); | 1330 | err = ov5693_power_get(priv); |
1330 | if (err) | 1331 | if (err) |
diff --git a/drivers/media/platform/tegra/camera/camera_common.c b/drivers/media/platform/tegra/camera/camera_common.c index c57cf8a2c..886dd2027 100644 --- a/drivers/media/platform/tegra/camera/camera_common.c +++ b/drivers/media/platform/tegra/camera/camera_common.c | |||
@@ -464,31 +464,22 @@ static int camera_common_mclk_enable(struct camera_common_data *s_data) | |||
464 | unsigned long mclk_init_rate = s_data->def_clk_freq; | 464 | unsigned long mclk_init_rate = s_data->def_clk_freq; |
465 | 465 | ||
466 | if (!pw) { | 466 | if (!pw) { |
467 | dev_err(&s_data->i2c_client->dev, "%s: no device power rail\n", | 467 | dev_err(s_data->dev, "%s: no device power rail\n", |
468 | __func__); | 468 | __func__); |
469 | return -EFAULT; | 469 | return -ENODEV; |
470 | } | 470 | } |
471 | 471 | ||
472 | dev_dbg(&s_data->i2c_client->dev, "%s: enable MCLK with %lu Hz\n", | 472 | dev_dbg(s_data->dev, "%s: enable MCLK with %lu Hz\n", |
473 | __func__, mclk_init_rate); | 473 | __func__, mclk_init_rate); |
474 | 474 | ||
475 | err = clk_set_rate(pw->mclk, mclk_init_rate); | 475 | err = clk_set_rate(pw->mclk, mclk_init_rate); |
476 | if (err) { | 476 | if (!err) |
477 | dev_err(&s_data->i2c_client->dev, "%s: error set rate\n", | 477 | err = clk_prepare_enable(pw->mclk); |
478 | __func__); | ||
479 | return err; | ||
480 | } | ||
481 | err = clk_prepare_enable(pw->mclk); | ||
482 | if (err) { | ||
483 | dev_err(&s_data->i2c_client->dev, "%s: error prepare enable\n", | ||
484 | __func__); | ||
485 | return err; | ||
486 | } | ||
487 | 478 | ||
488 | return 0; | 479 | return err; |
489 | } | 480 | } |
490 | 481 | ||
491 | static void camera_common_dpd_disable(struct camera_common_data *s_data) | 482 | void camera_common_dpd_disable(struct camera_common_data *s_data) |
492 | { | 483 | { |
493 | int i; | 484 | int i; |
494 | int io_idx; | 485 | int io_idx; |
@@ -499,12 +490,12 @@ static void camera_common_dpd_disable(struct camera_common_data *s_data) | |||
499 | for (i = 0; i < numports; i++) { | 490 | for (i = 0; i < numports; i++) { |
500 | io_idx = s_data->csi_port + i; | 491 | io_idx = s_data->csi_port + i; |
501 | tegra_io_dpd_disable(&camera_common_csi_io[io_idx]); | 492 | tegra_io_dpd_disable(&camera_common_csi_io[io_idx]); |
502 | dev_dbg(&s_data->i2c_client->dev, | 493 | dev_dbg(s_data->dev, |
503 | "%s: csi %d\n", __func__, io_idx); | 494 | "%s: csi %d\n", __func__, io_idx); |
504 | } | 495 | } |
505 | } | 496 | } |
506 | 497 | ||
507 | static void camera_common_dpd_enable(struct camera_common_data *s_data) | 498 | void camera_common_dpd_enable(struct camera_common_data *s_data) |
508 | { | 499 | { |
509 | int i; | 500 | int i; |
510 | int io_idx; | 501 | int io_idx; |
@@ -515,7 +506,7 @@ static void camera_common_dpd_enable(struct camera_common_data *s_data) | |||
515 | for (i = 0; i < numports; i++) { | 506 | for (i = 0; i < numports; i++) { |
516 | io_idx = s_data->csi_port + i; | 507 | io_idx = s_data->csi_port + i; |
517 | tegra_io_dpd_enable(&camera_common_csi_io[io_idx]); | 508 | tegra_io_dpd_enable(&camera_common_csi_io[io_idx]); |
518 | dev_dbg(&s_data->i2c_client->dev, | 509 | dev_dbg(s_data->dev, |
519 | "%s: csi %d\n", __func__, io_idx); | 510 | "%s: csi %d\n", __func__, io_idx); |
520 | } | 511 | } |
521 | } | 512 | } |
@@ -535,7 +526,7 @@ int camera_common_s_power(struct v4l2_subdev *sd, int on) | |||
535 | 526 | ||
536 | err = call_s_op(s_data, power_on); | 527 | err = call_s_op(s_data, power_on); |
537 | if (err) { | 528 | if (err) { |
538 | dev_err(&s_data->i2c_client->dev, | 529 | dev_err(s_data->dev, |
539 | "%s: error power on\n", __func__); | 530 | "%s: error power on\n", __func__); |
540 | camera_common_dpd_enable(s_data); | 531 | camera_common_dpd_enable(s_data); |
541 | camera_common_mclk_disable(s_data); | 532 | camera_common_mclk_disable(s_data); |