]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blob - drivers/media/platform/soc_camera/camera_common.c
media: camera-common: export symbols for modules
[sojka/nv-tegra/linux-3.10.git] / drivers / media / platform / soc_camera / camera_common.c
1 /*
2  * camera_common.c - utilities for tegra camera driver
3  *
4  * Copyright (c) 2015, 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 <media/camera_common.h>
20 #include <mach/io_dpd.h>
21
22 #define has_s_op(master, op) \
23         (master->ops && master->ops->op)
24 #define call_s_op(master, op) \
25         (has_s_op(master, op) ? \
26          master->ops->op(master) : 0)
27 #define call_s_ops(master, op, ...) \
28         (has_s_op(master, op) ? \
29          master->ops->op(master, __VA_ARGS__) : 0)
30
31 static const struct camera_common_colorfmt camera_common_color_fmts[] = {
32         {V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_COLORSPACE_SRGB},
33         {V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_COLORSPACE_SRGB},
34         {V4L2_MBUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB},
35         {V4L2_MBUS_FMT_RGBA8888_4X8_LE, V4L2_COLORSPACE_SRGB},
36 };
37
38 static struct tegra_io_dpd camera_common_csi_io[] = {
39         {
40                 .name                   = "CSIA",
41                 .io_dpd_reg_index       = 0,
42                 .io_dpd_bit             = 0x0,
43         },
44         {
45                 .name                   = "CSIB",
46                 .io_dpd_reg_index       = 0,
47                 .io_dpd_bit             = 0x1,
48         },
49         {
50                 .name                   = "CSIC",
51                 .io_dpd_reg_index       = 1,
52                 .io_dpd_bit             = 0xa,
53         },
54         {
55                 .name                   = "CSID",
56                 .io_dpd_reg_index       = 1,
57                 .io_dpd_bit             = 0xb,
58         },
59         {
60                 .name                   = "CSIE",
61                 .io_dpd_reg_index       = 1,
62                 .io_dpd_bit             = 0xc,
63         },
64         {
65                 .name                   = "CSIF",
66                 .io_dpd_reg_index       = 1,
67                 .io_dpd_bit             = 0xd,
68         },
69 };
70
71 int camera_common_g_ctrl(struct camera_common_data *s_data,
72                          struct v4l2_control *control)
73 {
74         int i;
75
76         for (i = 0; i < s_data->numctrls; i++) {
77                 if (s_data->ctrls[i]->id == control->id) {
78                         control->value = s_data->ctrls[i]->val;
79                         dev_dbg(&s_data->i2c_client->dev,
80                                  "%s: found control %s\n", __func__,
81                                  s_data->ctrls[i]->name);
82                         return 0;
83                 }
84         }
85
86         return -EFAULT;
87 }
88 EXPORT_SYMBOL(camera_common_g_ctrl);
89
90 int camera_common_regulator_get(struct i2c_client *client,
91                        struct regulator **vreg, const char *vreg_name)
92 {
93         struct regulator *reg = NULL;
94         int err = 0;
95
96         reg = devm_regulator_get(&client->dev, vreg_name);
97         if (unlikely(IS_ERR(reg))) {
98                 dev_err(&client->dev, "%s %s ERR: %p\n",
99                         __func__, vreg_name, reg);
100                 err = PTR_ERR(reg);
101                 reg = NULL;
102         } else
103                 dev_dbg(&client->dev, "%s: %s\n",
104                         __func__, vreg_name);
105
106         *vreg = reg;
107         return err;
108 }
109 EXPORT_SYMBOL(camera_common_regulator_get);
110
111 int camera_common_debugfs_show(struct seq_file *s, void *unused)
112 {
113         struct camera_common_data *s_data = s->private;
114
115         dev_dbg(&s_data->i2c_client->dev, "%s: ++\n", __func__);
116
117         return 0;
118 }
119
120 ssize_t camera_common_debugfs_write(
121         struct file *file,
122         char const __user *buf,
123         size_t count,
124         loff_t *offset)
125 {
126         struct camera_common_data *s_data =
127                 ((struct seq_file *)file->private_data)->private;
128         struct i2c_client *client = s_data->i2c_client;
129         int err = 0;
130         char buffer[MAX_BUFFER_SIZE];
131         u32 address;
132         u32 data;
133         u8 readback;
134
135         dev_dbg(&client->dev, "%s: ++\n", __func__);
136
137         if (copy_from_user(&buffer, buf, sizeof(buffer)))
138                 goto debugfs_write_fail;
139
140         if (sscanf(buf, "0x%x 0x%x", &address, &data) == 2)
141                 goto set_attr;
142         if (sscanf(buf, "0X%x 0X%x", &address, &data) == 2)
143                 goto set_attr;
144         if (sscanf(buf, "%d %d", &address, &data) == 2)
145                 goto set_attr;
146
147         if (sscanf(buf, "0x%x 0x%x", &address, &data) == 1)
148                 goto read;
149         if (sscanf(buf, "0X%x 0X%x", &address, &data) == 1)
150                 goto read;
151         if (sscanf(buf, "%d %d", &address, &data) == 1)
152                 goto read;
153
154         dev_err(&client->dev, "SYNTAX ERROR: %s\n", buf);
155         return -EFAULT;
156
157 set_attr:
158         dev_info(&client->dev,
159                         "new address = %x, data = %x\n", address, data);
160         err |= call_s_ops(s_data, write_reg, address, data);
161 read:
162         err |= call_s_ops(s_data, read_reg, address, &readback);
163         dev_info(&client->dev,
164                         "wrote to address 0x%x with value 0x%x\n",
165                         address, readback);
166
167         if (err)
168                 goto debugfs_write_fail;
169
170         return count;
171
172 debugfs_write_fail:
173         dev_err(&client->dev,
174                         "%s: test pattern write failed\n", __func__);
175         return -EFAULT;
176 }
177
178 int camera_common_debugfs_open(struct inode *inode, struct file *file)
179 {
180         struct camera_common_data *s_data = inode->i_private;
181         struct i2c_client *client = s_data->i2c_client;
182
183         dev_dbg(&client->dev, "%s: ++\n", __func__);
184
185         return single_open(file, camera_common_debugfs_show, inode->i_private);
186 }
187
188 static const struct file_operations camera_common_debugfs_fops = {
189         .open           = camera_common_debugfs_open,
190         .read           = seq_read,
191         .write          = camera_common_debugfs_write,
192         .llseek         = seq_lseek,
193         .release        = single_release,
194 };
195
196 void camera_common_remove_debugfs(
197                 struct camera_common_data *s_data)
198 {
199         struct i2c_client *client = s_data->i2c_client;
200
201         dev_dbg(&client->dev, "%s: ++\n", __func__);
202
203         debugfs_remove_recursive(s_data->debugdir);
204         s_data->debugdir = NULL;
205 }
206 EXPORT_SYMBOL(camera_common_remove_debugfs);
207
208 void camera_common_create_debugfs(
209                 struct camera_common_data *s_data,
210                 const char *name)
211 {
212         struct dentry *err;
213         struct i2c_client *client = s_data->i2c_client;
214
215         dev_dbg(&client->dev, "%s %s\n", __func__, name);
216
217         s_data->debugdir =
218                 debugfs_create_dir(name, NULL);
219         if (!s_data->debugdir)
220                 goto remove_debugfs;
221
222         err = debugfs_create_file("d",
223                                 S_IWUSR | S_IRUGO,
224                                 s_data->debugdir, s_data,
225                                 &camera_common_debugfs_fops);
226         if (!err)
227                 goto remove_debugfs;
228
229         return;
230 remove_debugfs:
231         dev_err(&client->dev, "couldn't create debugfs\n");
232         camera_common_remove_debugfs(s_data);
233 }
234 EXPORT_SYMBOL(camera_common_create_debugfs);
235
236 /* Find a data format by a pixel code in an array */
237 const struct camera_common_colorfmt *camera_common_find_datafmt(
238                 enum v4l2_mbus_pixelcode code)
239 {
240         int i;
241
242         for (i = 0; i < ARRAY_SIZE(camera_common_color_fmts); i++)
243                 if (camera_common_color_fmts[i].code == code)
244                         return camera_common_color_fmts + i;
245
246         return NULL;
247 }
248 EXPORT_SYMBOL(camera_common_find_datafmt);
249
250 int camera_common_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
251                          enum v4l2_mbus_pixelcode *code)
252 {
253         if ((unsigned int)index >= ARRAY_SIZE(camera_common_color_fmts))
254                 return -EINVAL;
255
256         *code = camera_common_color_fmts[index].code;
257         return 0;
258 }
259 EXPORT_SYMBOL(camera_common_enum_fmt);
260
261 int camera_common_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
262 {
263         struct i2c_client *client = v4l2_get_subdevdata(sd);
264         struct camera_common_data *s_data = to_camera_common_data(client);
265         struct v4l2_control hdr_control;
266         const struct camera_common_frmfmt *frmfmt = s_data->frmfmt;
267         int hdr_en;
268         int err;
269         int i;
270         bool fmt_match = false;
271
272         dev_dbg(&client->dev, "%s: size %i x %i\n", __func__,
273                  mf->width, mf->height);
274
275         /* check hdr enable ctrl */
276         hdr_control.id = V4L2_CID_HDR_EN;
277
278         err = v4l2_g_ctrl(s_data->ctrl_handler, &hdr_control);
279         if (err < 0) {
280                 dev_dbg(&client->dev, "could not find device ctrl.\n");
281                 hdr_control.value = 0;
282         }
283
284         hdr_en = switch_ctrl_qmenu[hdr_control.value];
285
286         s_data->mode = s_data->def_mode;
287         s_data->fmt_width = s_data->def_width;
288         s_data->fmt_height = s_data->def_height;
289
290         for (i = 0; i < s_data->numfmts; i++) {
291                 if (mf->width == frmfmt[i].size.width &&
292                     mf->height == frmfmt[i].size.height &&
293                     hdr_en == frmfmt[i].hdr_en) {
294                         s_data->mode = frmfmt[i].mode;
295                         s_data->fmt_width = mf->width;
296                         s_data->fmt_height = mf->height;
297                         fmt_match = true;
298                         break;
299                 }
300         }
301
302         if (i == s_data->numfmts)
303                 dev_dbg(&client->dev,
304                         "%s: invalid resolution supplied to set mode %d %d\n",
305                         __func__, mf->width, mf->height);
306
307         if (mf->code != V4L2_MBUS_FMT_SRGGB8_1X8 &&
308                 mf->code != V4L2_MBUS_FMT_SRGGB10_1X10 &&
309                 mf->code != V4L2_MBUS_FMT_RGBA8888_4X8_LE &&
310                 mf->code != V4L2_MBUS_FMT_UYVY8_2X8)
311                 mf->code = V4L2_MBUS_FMT_SRGGB10_1X10;
312
313         if (!fmt_match) {
314                 mf->width = s_data->def_width;
315                 mf->height = s_data->def_height;
316         }
317
318         mf->field = V4L2_FIELD_NONE;
319         mf->colorspace = V4L2_COLORSPACE_SRGB;
320
321         return 0;
322 }
323 EXPORT_SYMBOL(camera_common_try_fmt);
324
325 int camera_common_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
326 {
327         struct i2c_client *client = v4l2_get_subdevdata(sd);
328         struct camera_common_data *s_data = to_camera_common_data(client);
329
330         dev_dbg(&client->dev, "%s(%u) size %i x %i\n", __func__,
331                         mf->code, mf->width, mf->height);
332
333         /* MIPI CSI could have changed the format, double-check */
334         if (!camera_common_find_datafmt(mf->code))
335                 return -EINVAL;
336
337         camera_common_try_fmt(sd, mf);
338
339         s_data->colorfmt = camera_common_find_datafmt(mf->code);
340
341         return 0;
342 }
343 EXPORT_SYMBOL(camera_common_s_fmt);
344
345 int camera_common_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
346 {
347         struct i2c_client *client = v4l2_get_subdevdata(sd);
348         struct camera_common_data *s_data = to_camera_common_data(client);
349         const struct camera_common_colorfmt *fmt = s_data->colorfmt;
350
351         dev_dbg(&client->dev, "%s++\n", __func__);
352
353         mf->code        = fmt->code;
354         mf->colorspace  = fmt->colorspace;
355         mf->width       = s_data->fmt_width;
356         mf->height      = s_data->fmt_height;
357         mf->field       = V4L2_FIELD_NONE;
358
359         return 0;
360 }
361 EXPORT_SYMBOL(camera_common_g_fmt);
362
363 int camera_common_g_chip_ident(struct v4l2_subdev *sd,
364                              struct v4l2_dbg_chip_ident *id)
365 {
366         struct i2c_client *client = v4l2_get_subdevdata(sd);
367         struct camera_common_data *s_data = to_camera_common_data(client);
368
369         if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
370                 return -EINVAL;
371
372         if (id->match.addr != client->addr)
373                 return -ENODEV;
374
375         id->ident       = s_data->ident;
376         id->revision    = 0;
377
378         return 0;
379 }
380
381 static void camera_common_mclk_disable(struct camera_common_data *s_data)
382 {
383         struct camera_common_power_rail *pw = s_data->power;
384
385         if (!pw) {
386                 dev_err(&s_data->i2c_client->dev, "%s: no device power rail\n",
387                         __func__);
388                 return;
389         }
390
391         dev_dbg(&s_data->i2c_client->dev, "%s: disable MCLK\n", __func__);
392         clk_disable_unprepare(pw->mclk);
393 }
394
395 static int camera_common_mclk_enable(struct camera_common_data *s_data)
396 {
397         int err;
398         struct camera_common_power_rail *pw = s_data->power;
399         unsigned long mclk_init_rate = s_data->def_clk_freq;
400
401         if (!pw) {
402                 dev_err(&s_data->i2c_client->dev, "%s: no device power rail\n",
403                         __func__);
404                 return -EFAULT;
405         }
406
407         dev_dbg(&s_data->i2c_client->dev, "%s: enable MCLK with %lu Hz\n",
408                 __func__, mclk_init_rate);
409
410         err = clk_set_rate(pw->mclk, mclk_init_rate);
411         if (!err)
412                 err = clk_prepare_enable(pw->mclk);
413         return err;
414 }
415
416 static void camera_common_dpd_disable(struct camera_common_data *s_data)
417 {
418         int i;
419         int io_idx;
420         /* 2 lanes per port, divide by two to get numports */
421         int numports = (s_data->numlanes + 1) >> 1;
422
423         /* disable CSI IOs DPD mode to turn on camera */
424         for (i = 0; i < numports; i++) {
425                 io_idx = s_data->csi_port + i;
426                 tegra_io_dpd_disable(&camera_common_csi_io[io_idx]);
427                         dev_dbg(&s_data->i2c_client->dev,
428                          "%s: csi %d\n", __func__, io_idx);
429         }
430 }
431
432 static void camera_common_dpd_enable(struct camera_common_data *s_data)
433 {
434         int i;
435         int io_idx;
436         /* 2 lanes per port, divide by two to get numports */
437         int numports = (s_data->numlanes + 1) >> 1;
438
439         /* disable CSI IOs DPD mode to turn on camera */
440         for (i = 0; i < numports; i++) {
441                 io_idx = s_data->csi_port + i;
442                 tegra_io_dpd_enable(&camera_common_csi_io[io_idx]);
443                         dev_dbg(&s_data->i2c_client->dev,
444                          "%s: csi %d\n", __func__, io_idx);
445         }
446 }
447
448 int camera_common_s_power(struct v4l2_subdev *sd, int on)
449 {
450         int err;
451         struct i2c_client *client = v4l2_get_subdevdata(sd);
452         struct camera_common_data *s_data = to_camera_common_data(client);
453
454         if (on) {
455                 err = camera_common_mclk_enable(s_data);
456                 camera_common_dpd_disable(s_data);
457                 if (!err)
458                         err = call_s_op(s_data, power_on);
459                 if (err) {
460                         camera_common_dpd_enable(s_data);
461                         camera_common_mclk_disable(s_data);
462                 }
463                 return err;
464         } else if (!on) {
465                 call_s_op(s_data, power_off);
466                 camera_common_dpd_enable(s_data);
467                 camera_common_mclk_disable(s_data);
468                 return 0;
469         } else
470                 return -EINVAL;
471 }
472 EXPORT_SYMBOL(camera_common_s_power);
473
474 int camera_common_g_mbus_config(struct v4l2_subdev *sd,
475                                 struct v4l2_mbus_config *cfg)
476 {
477         cfg->type = V4L2_MBUS_CSI2;
478         cfg->flags = V4L2_MBUS_CSI2_4_LANE |
479                 V4L2_MBUS_CSI2_CHANNEL_0 |
480                 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
481
482         return 0;
483 }
484 EXPORT_SYMBOL(camera_common_g_mbus_config);