diff options
Diffstat (limited to 'drivers/media/i2c/lc898212.c')
-rw-r--r-- | drivers/media/i2c/lc898212.c | 645 |
1 files changed, 645 insertions, 0 deletions
diff --git a/drivers/media/i2c/lc898212.c b/drivers/media/i2c/lc898212.c new file mode 100644 index 000000000..44cdb876e --- /dev/null +++ b/drivers/media/i2c/lc898212.c | |||
@@ -0,0 +1,645 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #include <linux/delay.h> | ||
18 | #include <linux/fs.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/miscdevice.h> | ||
21 | #include <linux/regulator/consumer.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_device.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | |||
31 | #include <media/camera_common.h> | ||
32 | |||
33 | #include "tegra_camera_dev_mfi.h" | ||
34 | |||
35 | #define LC898212_ACTUATOR_RANGE 1023 | ||
36 | #define LC898212_POS_LOW_DEFAULT (0) | ||
37 | #define LC898212_POS_HIGH_DEFAULT (1023) | ||
38 | #define LC898212_FOCUS_MACRO (896) | ||
39 | #define LC898212_FOCUS_INFINITY (128) | ||
40 | #define LC898212_PWR_DEV_OFF (0) | ||
41 | #define LC898212_PWR_DEV_ON (1) | ||
42 | |||
43 | #define SETTLETIME_MS (15) | ||
44 | #define FOCAL_LENGTH (47300) | ||
45 | #define MAX_APERTURE (22000) | ||
46 | #define FNUMBER (22000) | ||
47 | #define LC898212_MOVE_TIME_VALUE (0x43) | ||
48 | |||
49 | #define LC898212_MAX_RETRIES (3) | ||
50 | |||
51 | #define LC898212_WAIT_REPEAT 0xFE | ||
52 | #define LC898212_TABLE_END 0xFF | ||
53 | |||
54 | #define LC898212_REG_ACCESS 0x1 | ||
55 | #define LC898212_RAM_ACCESS 0x2 | ||
56 | |||
57 | #define AF_MIN 0 | ||
58 | #define AF_MAX 1023 | ||
59 | #define AF_RANGE (AF_MAX - AF_MIN + 1) | ||
60 | |||
61 | #define LC898212_RZ 0x04 | ||
62 | #define LC898212_ADOFFSET 0x3C | ||
63 | #define LC898212_EQENBL 0x87 | ||
64 | |||
65 | /** | ||
66 | * standard + custom controls | ||
67 | * custom controls not added for this focuser yet | ||
68 | */ | ||
69 | #define NUM_FOCUS_STD_CTRLS 1 | ||
70 | #define NUM_FOCUS_CUSTOM_CTRLS 0 | ||
71 | #define NUM_FOCUS_CTRLS (NUM_FOCUS_STD_CTRLS + NUM_FOCUS_CUSTOM_CTRLS) | ||
72 | |||
73 | static int lc898212_s_ctrl(struct v4l2_ctrl *ctrl); | ||
74 | |||
75 | struct lc898212_reg { | ||
76 | u8 type; | ||
77 | u8 addr; | ||
78 | u16 val; | ||
79 | }; | ||
80 | |||
81 | struct lc898212 { | ||
82 | struct i2c_client *i2c_client; | ||
83 | struct v4l2_subdev *subdev; | ||
84 | struct media_pad pad; | ||
85 | |||
86 | struct v4l2_ctrl_handler ctrl_handler; | ||
87 | struct regulator *regulator; | ||
88 | struct camera_common_focuser_data *s_data; | ||
89 | struct regmap *regmap8; | ||
90 | struct regmap *regmap16; | ||
91 | int numctrls; | ||
92 | struct camera_mfi_dev *cmfi_dev16; | ||
93 | bool support_mfi; | ||
94 | struct v4l2_ctrl *ctrls[]; | ||
95 | }; | ||
96 | |||
97 | static struct lc898212_reg lc898212_init_setting[] = { | ||
98 | {LC898212_REG_ACCESS, 0x80, 0x34}, | ||
99 | {LC898212_REG_ACCESS, 0x81, 0xA0}, | ||
100 | {LC898212_REG_ACCESS, 0x84, 0xE0}, | ||
101 | {LC898212_REG_ACCESS, 0x87, 0x05}, | ||
102 | {LC898212_REG_ACCESS, 0xA4, 0x24}, | ||
103 | {LC898212_RAM_ACCESS, 0x3A, 0x0000}, | ||
104 | {LC898212_RAM_ACCESS, 0x04, 0x0000}, | ||
105 | {LC898212_RAM_ACCESS, 0x02, 0x0000}, | ||
106 | {LC898212_RAM_ACCESS, 0x18, 0x0000}, | ||
107 | |||
108 | /* Filter Setting */ | ||
109 | {LC898212_RAM_ACCESS, 0x40, 0x4030}, | ||
110 | {LC898212_RAM_ACCESS, 0x42, 0x7150}, | ||
111 | {LC898212_RAM_ACCESS, 0x44, 0x8F90}, | ||
112 | {LC898212_RAM_ACCESS, 0x46, 0x61B0}, | ||
113 | {LC898212_RAM_ACCESS, 0x48, 0x7FF0}, | ||
114 | {LC898212_RAM_ACCESS, 0x4A, 0x3930}, | ||
115 | {LC898212_RAM_ACCESS, 0x4C, 0x4030}, | ||
116 | {LC898212_RAM_ACCESS, 0x4E, 0x8010}, | ||
117 | {LC898212_RAM_ACCESS, 0x50, 0x04F0}, | ||
118 | {LC898212_RAM_ACCESS, 0x52, 0x7610}, | ||
119 | {LC898212_RAM_ACCESS, 0x54, 0x2030}, | ||
120 | {LC898212_RAM_ACCESS, 0x56, 0x0000}, | ||
121 | {LC898212_RAM_ACCESS, 0x58, 0x7FF0}, | ||
122 | {LC898212_RAM_ACCESS, 0x5A, 0x0680}, | ||
123 | {LC898212_RAM_ACCESS, 0x5C, 0x72F0}, | ||
124 | {LC898212_RAM_ACCESS, 0x5E, 0x7F70}, | ||
125 | {LC898212_RAM_ACCESS, 0x60, 0x7ED0}, | ||
126 | {LC898212_RAM_ACCESS, 0x62, 0x7FF0}, | ||
127 | {LC898212_RAM_ACCESS, 0x64, 0x0000}, | ||
128 | {LC898212_RAM_ACCESS, 0x66, 0x0000}, | ||
129 | {LC898212_RAM_ACCESS, 0x68, 0x5130}, | ||
130 | {LC898212_RAM_ACCESS, 0x6A, 0x72F0}, | ||
131 | {LC898212_RAM_ACCESS, 0x6C, 0x8010}, | ||
132 | {LC898212_RAM_ACCESS, 0x6E, 0x0000}, | ||
133 | {LC898212_RAM_ACCESS, 0x70, 0x0000}, | ||
134 | {LC898212_RAM_ACCESS, 0x72, 0x18E0}, | ||
135 | {LC898212_RAM_ACCESS, 0x74, 0x4E30}, | ||
136 | {LC898212_RAM_ACCESS, 0x30, 0x0000}, | ||
137 | {LC898212_RAM_ACCESS, 0x76, 0x0C50}, | ||
138 | {LC898212_RAM_ACCESS, 0x78, 0x4000}, | ||
139 | |||
140 | {LC898212_REG_ACCESS, 0x86, 0x60}, | ||
141 | {LC898212_REG_ACCESS, 0x88, 0x70}, | ||
142 | {LC898212_RAM_ACCESS, 0x28, 0x8020}, | ||
143 | {LC898212_RAM_ACCESS, 0x4C, 0x4000}, | ||
144 | {LC898212_REG_ACCESS, 0x83, 0x2C}, | ||
145 | {LC898212_REG_ACCESS, 0x85, 0xC0}, | ||
146 | |||
147 | /* Repeat to read the register until the value turns 0x00 */ | ||
148 | {LC898212_REG_ACCESS, LC898212_WAIT_REPEAT, 0x85}, | ||
149 | |||
150 | {LC898212_REG_ACCESS, 0x84, 0xE3}, | ||
151 | {LC898212_REG_ACCESS, 0x97, 0x00}, | ||
152 | {LC898212_REG_ACCESS, 0x98, 0x42}, | ||
153 | {LC898212_REG_ACCESS, 0x99, 0x00}, | ||
154 | {LC898212_REG_ACCESS, 0x9A, 0x00}, | ||
155 | |||
156 | {LC898212_REG_ACCESS, LC898212_TABLE_END, 0x00} | ||
157 | }; | ||
158 | |||
159 | const struct of_device_id lc898212_of_match[] = { | ||
160 | { .compatible = "nvidia,lc898212", }, | ||
161 | { }, | ||
162 | }; | ||
163 | MODULE_DEVICE_TABLE(of, lc898212_of_match); | ||
164 | |||
165 | static int lc898212_set_position(struct lc898212 *priv, u32 position) | ||
166 | { | ||
167 | int ret = 0; | ||
168 | s16 new_pos = 0; | ||
169 | struct camera_common_focuser_data *s_data = priv->s_data; | ||
170 | struct nv_focuser_config *cfg = &s_data->config; | ||
171 | |||
172 | dev_dbg(&s_data->i2c_client->dev, "%s++\n", __func__); | ||
173 | if (position < cfg->pos_actual_low || | ||
174 | position > cfg->pos_actual_high) { | ||
175 | dev_dbg(&priv->i2c_client->dev, | ||
176 | "%s: position(%d) out of bound([%d, %d])\n", | ||
177 | __func__, position, cfg->pos_actual_low, | ||
178 | cfg->pos_actual_high); | ||
179 | if (position < cfg->pos_actual_low) | ||
180 | position = cfg->pos_actual_low; | ||
181 | if (position > cfg->pos_actual_high) | ||
182 | position = cfg->pos_actual_high; | ||
183 | } | ||
184 | |||
185 | /* unsigned 10 bit to signed 16 bit */ | ||
186 | new_pos = ((s16) position - AF_RANGE / 2) * 64; | ||
187 | |||
188 | if (priv->support_mfi) { | ||
189 | ret = tegra_camera_dev_mfi_clear(priv->cmfi_dev16); | ||
190 | ret |= tegra_camera_dev_mfi_wr_add(priv->cmfi_dev16, | ||
191 | LC898212_RZ, | ||
192 | (u16) new_pos); | ||
193 | } else { | ||
194 | ret = regmap_write(priv->regmap16, LC898212_RZ, (u16) new_pos); | ||
195 | } | ||
196 | |||
197 | dev_dbg(&s_data->i2c_client->dev, "%s--\n", __func__); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * V4l2 controls | ||
203 | */ | ||
204 | |||
205 | static const struct v4l2_ctrl_ops lc898212_ctrl_ops = { | ||
206 | .s_ctrl = lc898212_s_ctrl, | ||
207 | }; | ||
208 | |||
209 | static int lc898212_s_ctrl(struct v4l2_ctrl *ctrl) | ||
210 | { | ||
211 | struct lc898212 *priv = | ||
212 | container_of(ctrl->handler, struct lc898212, ctrl_handler); | ||
213 | int err; | ||
214 | |||
215 | dev_dbg(&priv->s_data->i2c_client->dev, "%s++\n", __func__); | ||
216 | /* check for power state */ | ||
217 | if (priv->s_data->pwr_dev == LC898212_PWR_DEV_OFF) | ||
218 | return -ENODEV; | ||
219 | |||
220 | switch (ctrl->id) { | ||
221 | case V4L2_CID_FOCUS_ABSOLUTE: | ||
222 | err = lc898212_set_position(priv, ctrl->val); | ||
223 | break; | ||
224 | default: | ||
225 | pr_err("%s: unknown v4l2 ctlr id\n", __func__); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | |||
229 | return err; | ||
230 | } | ||
231 | |||
232 | static int lc898212_ctrls_init(struct camera_common_focuser_data *s_data) | ||
233 | { | ||
234 | struct lc898212 *priv = (struct lc898212 *)s_data->priv; | ||
235 | struct i2c_client *client = priv->i2c_client; | ||
236 | struct v4l2_ctrl *ctrl; | ||
237 | struct nv_focuser_config *cfg = &s_data->config; | ||
238 | int min = cfg->pos_actual_low; | ||
239 | int max = cfg->pos_actual_high; | ||
240 | int def = priv->s_data->def_position; | ||
241 | int err = 0; | ||
242 | |||
243 | v4l2_ctrl_handler_init(&priv->ctrl_handler, priv->numctrls); | ||
244 | priv->subdev->ctrl_handler = &priv->ctrl_handler; | ||
245 | err = priv->ctrl_handler.error; | ||
246 | if (err) { | ||
247 | dev_err(&client->dev, "Error %d adding controls\n", err); | ||
248 | goto error; | ||
249 | } | ||
250 | |||
251 | /* add std controls */ | ||
252 | ctrl = v4l2_ctrl_new_std(&priv->ctrl_handler, &lc898212_ctrl_ops, | ||
253 | V4L2_CID_FOCUS_ABSOLUTE, min, max, 1, def); | ||
254 | if (ctrl == NULL) { | ||
255 | dev_err(&client->dev, "Error initializing controls\n"); | ||
256 | err = -EINVAL; | ||
257 | goto error; | ||
258 | } | ||
259 | priv->ctrls[0] = ctrl; | ||
260 | |||
261 | err = v4l2_ctrl_handler_setup(&priv->ctrl_handler); | ||
262 | if (err) { | ||
263 | dev_err(&client->dev, "Error setting default controls\n"); | ||
264 | goto error; | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | error: | ||
269 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | ||
270 | return err; | ||
271 | } | ||
272 | |||
273 | static int lc898212_write_table(struct lc898212 *priv, | ||
274 | const struct lc898212_reg table[]) | ||
275 | { | ||
276 | int err; | ||
277 | const struct lc898212_reg *next; | ||
278 | u16 val; | ||
279 | |||
280 | for (next = table; next->addr != LC898212_TABLE_END; next++) { | ||
281 | val = next->val; | ||
282 | |||
283 | if (next->addr == LC898212_WAIT_REPEAT) { | ||
284 | u8 data = 0; | ||
285 | u8 count = 0; | ||
286 | |||
287 | err = regmap_read(priv->regmap8, val, | ||
288 | (unsigned int *) &data); | ||
289 | if (err) { | ||
290 | pr_err("%s: regmap_read: %d\n", __func__, err); | ||
291 | return err; | ||
292 | } | ||
293 | while (data != 0) { | ||
294 | if (count >= 10) | ||
295 | return -EFAULT; /* focuser not ready */ | ||
296 | |||
297 | usleep_range(10, 20); | ||
298 | err = regmap_read(priv->regmap8, val, | ||
299 | (unsigned int *) &data); | ||
300 | if (err) { | ||
301 | pr_err("%s: regmap_read: %d\n", | ||
302 | __func__, err); | ||
303 | return err; | ||
304 | } | ||
305 | count++; | ||
306 | } | ||
307 | continue; | ||
308 | } | ||
309 | |||
310 | if (next->type == LC898212_RAM_ACCESS) | ||
311 | err = regmap_write(priv->regmap16, next->addr, val); | ||
312 | else | ||
313 | err = regmap_write(priv->regmap8, next->addr, val); | ||
314 | if (err) { | ||
315 | pr_err("%s:lc898212_write_table:%d", __func__, err); | ||
316 | return err; | ||
317 | } | ||
318 | } | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static unsigned int convert_signed16b_to_unsigned10b(s16 data) | ||
323 | { | ||
324 | return (u16)(data / 64 + (AF_RANGE>>1)); | ||
325 | } | ||
326 | |||
327 | static int lc898212_init(struct lc898212 *priv) | ||
328 | { | ||
329 | int err; | ||
330 | int data; | ||
331 | |||
332 | err = lc898212_write_table(priv, lc898212_init_setting); | ||
333 | |||
334 | err |= regmap_read(priv->regmap16, LC898212_ADOFFSET, &data); | ||
335 | priv->s_data->def_position = | ||
336 | convert_signed16b_to_unsigned10b((s16)(data & 0xffff)); | ||
337 | err |= regmap_write(priv->regmap16, LC898212_RZ, data); | ||
338 | |||
339 | /* Servo On */ | ||
340 | err |= regmap_write(priv->regmap8, LC898212_EQENBL, 0x85); | ||
341 | |||
342 | return err; | ||
343 | } | ||
344 | |||
345 | static int lc898212_load_config(struct camera_common_focuser_data *s_data) | ||
346 | { | ||
347 | struct nv_focuser_config *cfg = &s_data->config; | ||
348 | |||
349 | /* load default configuration */ | ||
350 | /* TODO: parse these values from DT */ | ||
351 | |||
352 | cfg->focal_length = FOCAL_LENGTH; | ||
353 | cfg->fnumber = FNUMBER; | ||
354 | cfg->max_aperture = MAX_APERTURE; | ||
355 | cfg->range_ends_reversed = 0; | ||
356 | |||
357 | cfg->pos_working_low = LC898212_FOCUS_INFINITY; | ||
358 | cfg->pos_working_high = LC898212_FOCUS_MACRO; | ||
359 | cfg->pos_actual_low = LC898212_POS_LOW_DEFAULT; | ||
360 | cfg->pos_actual_high = LC898212_POS_HIGH_DEFAULT; | ||
361 | |||
362 | cfg->num_focuser_sets = 1; | ||
363 | cfg->focuser_set[0].macro = LC898212_FOCUS_MACRO; | ||
364 | cfg->focuser_set[0].hyper = LC898212_FOCUS_INFINITY; | ||
365 | cfg->focuser_set[0].inf = LC898212_FOCUS_INFINITY; | ||
366 | cfg->focuser_set[0].settle_time = SETTLETIME_MS; | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int lc898212_power_off(struct camera_common_focuser_data *s_data) | ||
372 | { | ||
373 | struct lc898212 *priv = (struct lc898212 *)s_data->priv; | ||
374 | |||
375 | dev_dbg(&s_data->i2c_client->dev, "%s++\n", __func__); | ||
376 | if (priv->regulator) | ||
377 | regulator_disable(priv->regulator); | ||
378 | s_data->pwr_dev = LC898212_PWR_DEV_OFF; | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int lc898212_power_on(struct camera_common_focuser_data *s_data) | ||
384 | { | ||
385 | int err = 0; | ||
386 | struct lc898212 *priv = (struct lc898212 *)s_data->priv; | ||
387 | |||
388 | dev_dbg(&s_data->i2c_client->dev, "%s++\n", __func__); | ||
389 | if (priv->regulator) { | ||
390 | err = regulator_enable(priv->regulator); | ||
391 | if (err) { | ||
392 | dev_err(&s_data->i2c_client->dev, | ||
393 | "%s:regulator enabled failed\n", __func__); | ||
394 | return err; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | err = lc898212_init(priv); | ||
399 | if (err) | ||
400 | return err; | ||
401 | |||
402 | s_data->pwr_dev = LC898212_PWR_DEV_ON; | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static struct camera_common_focuser_ops lc898212_ops = { | ||
408 | .power_on = lc898212_power_on, | ||
409 | .power_off = lc898212_power_off, | ||
410 | .load_config = lc898212_load_config, | ||
411 | .ctrls_init = lc898212_ctrls_init, | ||
412 | }; | ||
413 | |||
414 | #if 0 | ||
415 | static int lc898212_s_stream(struct v4l2_subdev *sd, int enable) | ||
416 | { | ||
417 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
418 | struct camera_common_focuser_data *s_data = | ||
419 | to_camera_common_focuser_data(client); | ||
420 | struct lc898212 *priv = (struct lc898212 *)s_data->priv; | ||
421 | struct v4l2_control control; | ||
422 | int err = 0; | ||
423 | |||
424 | dev_dbg(&client->dev, "%s++\n", __func__); | ||
425 | err = lc898212_init(priv); | ||
426 | if (err) | ||
427 | return err; | ||
428 | |||
429 | /* write override registers for focus position */ | ||
430 | control.id = V4L2_CID_FOCUS_ABSOLUTE; | ||
431 | err = v4l2_g_ctrl(&priv->ctrl_handler, &control); | ||
432 | err |= lc898212_set_position(priv, control.value); | ||
433 | if (err) | ||
434 | dev_dbg(&client->dev, "%s:warning focus pos %d set failed\n", | ||
435 | __func__, control.value); | ||
436 | |||
437 | dev_dbg(&client->dev, "%s--\n", __func__); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static struct v4l2_subdev_video_ops lc898212_subdev_video_ops = { | ||
442 | .s_stream = lc898212_s_stream, | ||
443 | }; | ||
444 | |||
445 | #endif | ||
446 | |||
447 | static int lc898212_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) | ||
448 | { | ||
449 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
450 | |||
451 | dev_dbg(&client->dev, "%s:\n", __func__); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static struct v4l2_subdev_core_ops lc898212_subdev_core_ops = { | ||
456 | .s_power = camera_common_focuser_s_power, | ||
457 | }; | ||
458 | |||
459 | static struct v4l2_subdev_ops lc898212_subdev_ops = { | ||
460 | .core = &lc898212_subdev_core_ops, | ||
461 | }; | ||
462 | |||
463 | static const struct v4l2_subdev_internal_ops lc898212_subdev_internal_ops = { | ||
464 | .open = lc898212_open, | ||
465 | }; | ||
466 | |||
467 | static const struct media_entity_operations lc898212_media_ops = { | ||
468 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
469 | .link_validate = v4l2_subdev_link_validate, | ||
470 | #endif | ||
471 | }; | ||
472 | |||
473 | static int lc898212_probe(struct i2c_client *client, | ||
474 | const struct i2c_device_id *id) | ||
475 | { | ||
476 | int err; | ||
477 | struct lc898212 *priv; | ||
478 | struct camera_common_focuser_data *common_data; | ||
479 | char dev_id[20]; | ||
480 | const char *p_mfi_str; | ||
481 | |||
482 | static struct regmap_config lc898212_regmap_config8 = { | ||
483 | .reg_bits = 8, | ||
484 | .val_bits = 8, | ||
485 | .name = "8bit", | ||
486 | }; | ||
487 | static struct regmap_config lc898212_regmap_config16 = { | ||
488 | .reg_bits = 8, | ||
489 | .val_bits = 16, | ||
490 | .name = "16bit", | ||
491 | }; | ||
492 | |||
493 | pr_info("[lc898212]: probing sensor\n"); | ||
494 | |||
495 | common_data = devm_kzalloc(&client->dev, | ||
496 | sizeof(struct camera_common_focuser_data), GFP_KERNEL); | ||
497 | if (!common_data) | ||
498 | return -ENOMEM; | ||
499 | |||
500 | priv = devm_kzalloc(&client->dev, (sizeof(struct lc898212) + | ||
501 | sizeof(struct v4l2_ctrl *) * NUM_FOCUS_CTRLS), GFP_KERNEL); | ||
502 | if (!priv) | ||
503 | return -ENOMEM; | ||
504 | |||
505 | priv->regulator = devm_regulator_get(&client->dev, "vvcm"); | ||
506 | if (IS_ERR(priv->regulator)) { | ||
507 | dev_err(&client->dev, "unable to get regulator %s\n", | ||
508 | dev_name(&client->dev)); | ||
509 | priv->regulator = NULL; | ||
510 | } | ||
511 | |||
512 | priv->regmap8 = devm_regmap_init_i2c(client, | ||
513 | &lc898212_regmap_config8); | ||
514 | if (IS_ERR(priv->regmap8)) { | ||
515 | err = PTR_ERR(priv->regmap8); | ||
516 | dev_err(&client->dev, | ||
517 | "Failed to allocate register map 8: %d\n", err); | ||
518 | goto ERROR_RET; | ||
519 | } | ||
520 | priv->regmap16 = devm_regmap_init_i2c(client, | ||
521 | &lc898212_regmap_config16); | ||
522 | if (IS_ERR(priv->regmap16)) { | ||
523 | err = PTR_ERR(priv->regmap16); | ||
524 | dev_err(&client->dev, | ||
525 | "Failed to allocate register map 16: %d\n", err); | ||
526 | goto ERROR_RET; | ||
527 | } | ||
528 | |||
529 | common_data->ops = &lc898212_ops; | ||
530 | common_data->ctrl_handler = &priv->ctrl_handler; | ||
531 | common_data->i2c_client = client; | ||
532 | common_data->ctrls = priv->ctrls; | ||
533 | common_data->priv = (void *)priv; | ||
534 | priv->numctrls = NUM_FOCUS_CTRLS; | ||
535 | priv->i2c_client = client; | ||
536 | priv->s_data = common_data; | ||
537 | priv->subdev = &common_data->subdev; | ||
538 | priv->subdev->dev = &client->dev; | ||
539 | |||
540 | if (client->dev.of_node) { | ||
541 | err = of_property_read_string(client->dev.of_node, | ||
542 | "support_mfi", | ||
543 | &p_mfi_str); | ||
544 | if (err < 0) { | ||
545 | dev_err(&client->dev, | ||
546 | "%s unable to read MFI property\n", | ||
547 | __func__); | ||
548 | goto ERROR_RET; | ||
549 | } | ||
550 | |||
551 | priv->support_mfi = !strcmp(p_mfi_str, "true") ? true : false; | ||
552 | |||
553 | if (priv->support_mfi) { | ||
554 | int remain; | ||
555 | |||
556 | memset(dev_id, 0, sizeof(dev_id)); | ||
557 | strncpy(dev_id, "lc898212", (sizeof(dev_id) - 1)); | ||
558 | /* calculate how many bytes remaining in dev_id[] */ | ||
559 | remain = sizeof(dev_id) - strlen(dev_id) - 1; | ||
560 | /* strncat most of 'remain' bytes from dev_name[] */ | ||
561 | strncat(dev_id, dev_name(&client->dev), remain); | ||
562 | err = tegra_camera_dev_mfi_add_regmap(&priv->cmfi_dev16, | ||
563 | dev_id, priv->regmap16); | ||
564 | if (err < 0) { | ||
565 | dev_err(&client->dev, | ||
566 | "%s unable to add to mfi regmap\n", | ||
567 | __func__); | ||
568 | goto ERROR_RET; | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | |||
573 | err = camera_common_focuser_init(common_data); | ||
574 | if (err) { | ||
575 | dev_err(&client->dev, "unable to initialize focuser\n"); | ||
576 | goto ERROR_RET; | ||
577 | } | ||
578 | |||
579 | v4l2_i2c_subdev_init(priv->subdev, client, &lc898212_subdev_ops); | ||
580 | |||
581 | priv->subdev->internal_ops = &lc898212_subdev_internal_ops; | ||
582 | priv->subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | | ||
583 | V4L2_SUBDEV_FL_HAS_EVENTS; | ||
584 | |||
585 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
586 | priv->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
587 | priv->subdev->entity.type = MEDIA_ENT_T_V4L2_SUBDEV; | ||
588 | priv->subdev->entity.ops = &lc898212_media_ops; | ||
589 | err = media_entity_init(&priv->subdev->entity, 1, &priv->pad, 0); | ||
590 | if (err < 0) { | ||
591 | dev_err(&client->dev, "unable to init media entity\n"); | ||
592 | goto ERROR_RET; | ||
593 | } | ||
594 | #endif | ||
595 | |||
596 | err = v4l2_async_register_subdev(priv->subdev); | ||
597 | if (err) | ||
598 | goto ERROR_RET; | ||
599 | |||
600 | dev_dbg(&client->dev, "Detected lc898212 sensor\n"); | ||
601 | return 0; | ||
602 | |||
603 | ERROR_RET: | ||
604 | dev_err(&client->dev, "lc898212: probing sensor failed!!\n"); | ||
605 | return err; | ||
606 | } | ||
607 | |||
608 | static int lc898212_remove(struct i2c_client *client) | ||
609 | { | ||
610 | struct camera_common_focuser_data *s_data = | ||
611 | to_camera_common_focuser_data(client); | ||
612 | struct lc898212 *priv = (struct lc898212 *)s_data->priv; | ||
613 | |||
614 | v4l2_async_unregister_subdev(priv->subdev); | ||
615 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
616 | media_entity_cleanup(&priv->subdev->entity); | ||
617 | #endif | ||
618 | v4l2_ctrl_handler_free(&priv->ctrl_handler); | ||
619 | |||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | static const struct i2c_device_id lc898212_id[] = { | ||
624 | { "lc898212", 0 }, | ||
625 | { }, | ||
626 | }; | ||
627 | |||
628 | MODULE_DEVICE_TABLE(i2c, lc898212_id); | ||
629 | |||
630 | static struct i2c_driver lc898212_i2c_driver = { | ||
631 | .driver = { | ||
632 | .name = "lc898212", | ||
633 | .owner = THIS_MODULE, | ||
634 | .of_match_table = of_match_ptr(lc898212_of_match), | ||
635 | }, | ||
636 | .probe = lc898212_probe, | ||
637 | .remove = lc898212_remove, | ||
638 | .id_table = lc898212_id, | ||
639 | }; | ||
640 | |||
641 | module_i2c_driver(lc898212_i2c_driver); | ||
642 | |||
643 | MODULE_DESCRIPTION("I2C driver for LC898212"); | ||
644 | MODULE_AUTHOR("Bhanu Murthy V <bmurthyv@nvidia.com>"); | ||
645 | MODULE_LICENSE("GPL v2"); | ||