aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Brown <oliver.brown@freescale.com>2013-09-08 16:05:28 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:37 -0400
commit16afcaab006ca76784cf64e67678f4b754f84500 (patch)
treea7159b266bb3cd3abb8d6d34eacddca5b3b4cd70
parent9ec0aa2f9c10c1ca6724511b75c3e5bd48dc4fa2 (diff)
ENGR00278667-1 [mxc_v4l2_capture]: Add adv7180 driver in 3.10.9 Kernel
Copied file from 3.5.7 Kernel commit de6459732a23402cbe520812bf4202299330fd68 Author: Oliver Brown <oliver.brown@freescale.com> Date: Mon Jun 24 16:41:17 2013 -0500 Added missing call to clk_disable_unprepare() in adv7180_probe. Signed-off-by: Oliver Brown <oliver.brown@freescale.com>
-rw-r--r--drivers/media/platform/mxc/capture/Kconfig6
-rw-r--r--drivers/media/platform/mxc/capture/Makefile3
-rw-r--r--drivers/media/platform/mxc/capture/adv7180.c1344
3 files changed, 1353 insertions, 0 deletions
diff --git a/drivers/media/platform/mxc/capture/Kconfig b/drivers/media/platform/mxc/capture/Kconfig
index 6f253c1e45f5..cee7aa31f2d1 100644
--- a/drivers/media/platform/mxc/capture/Kconfig
+++ b/drivers/media/platform/mxc/capture/Kconfig
@@ -30,6 +30,12 @@ config MXC_CAMERA_OV5640_MIPI
30 ---help--- 30 ---help---
31 If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here. 31 If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
32 32
33config MXC_TVIN_ADV7180
34 tristate "Analog Device adv7180 TV Decoder Input support"
35 depends on !VIDEO_MXC_EMMA_CAMERA && I2C
36 ---help---
37 If you plan to use the adv7180 video decoder with your MXC system, say Y here.
38
33choice 39choice
34 prompt "Select Overlay Rounting" 40 prompt "Select Overlay Rounting"
35 default MXC_IPU_DEVICE_QUEUE_SDC 41 default MXC_IPU_DEVICE_QUEUE_SDC
diff --git a/drivers/media/platform/mxc/capture/Makefile b/drivers/media/platform/mxc/capture/Makefile
index 0f5eb3d10192..4303c0a2ccdf 100644
--- a/drivers/media/platform/mxc/capture/Makefile
+++ b/drivers/media/platform/mxc/capture/Makefile
@@ -16,3 +16,6 @@ obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
16 16
17ov5640_camera_mipi-objs := ov5640_mipi.o 17ov5640_camera_mipi-objs := ov5640_mipi.o
18obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o 18obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
19
20adv7180_tvin-objs := adv7180.o
21obj-$(CONFIG_MXC_TVIN_ADV7180) += adv7180_tvin.o
diff --git a/drivers/media/platform/mxc/capture/adv7180.c b/drivers/media/platform/mxc/capture/adv7180.c
new file mode 100644
index 000000000000..ae17d7f25ff6
--- /dev/null
+++ b/drivers/media/platform/mxc/capture/adv7180.c
@@ -0,0 +1,1344 @@
1/*
2 * Copyright 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
3 */
4
5/*
6 * The code contained herein is licensed under the GNU General Public
7 * License. You may obtain a copy of the GNU General Public License
8 * Version 2 or later at the following locations:
9 *
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
12 */
13
14/*!
15 * @file adv7180.c
16 *
17 * @brief Analog Device ADV7180 video decoder functions
18 *
19 * @ingroup Camera
20 */
21
22#include <linux/clk.h>
23#include <linux/delay.h>
24#include <linux/device.h>
25#include <linux/i2c.h>
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/of_device.h>
29#include <linux/of_gpio.h>
30#include <linux/pinctrl/consumer.h>
31#include <linux/regulator/consumer.h>
32#include <media/v4l2-chip-ident.h>
33#include <media/v4l2-int-device.h>
34#include "mxc_v4l2_capture.h"
35
36#define ADV7180_VOLTAGE_ANALOG 1800000
37#define ADV7180_VOLTAGE_DIGITAL_CORE 1800000
38#define ADV7180_VOLTAGE_DIGITAL_IO 3300000
39#define ADV7180_VOLTAGE_PLL 1800000
40
41static struct regulator *dvddio_regulator;
42static struct regulator *dvdd_regulator;
43static struct regulator *avdd_regulator;
44static struct regulator *pvdd_regulator;
45static int pwn_gpio;
46
47static int adv7180_probe(struct i2c_client *adapter,
48 const struct i2c_device_id *id);
49static int adv7180_detach(struct i2c_client *client);
50
51static const struct i2c_device_id adv7180_id[] = {
52 {"adv7180", 0},
53 {},
54};
55
56MODULE_DEVICE_TABLE(i2c, adv7180_id);
57
58static struct i2c_driver adv7180_i2c_driver = {
59 .driver = {
60 .owner = THIS_MODULE,
61 .name = "adv7180",
62 },
63 .probe = adv7180_probe,
64 .remove = adv7180_detach,
65 .id_table = adv7180_id,
66};
67
68/*!
69 * Maintains the information on the current state of the sensor.
70 */
71struct sensor {
72 struct sensor_data sen;
73 v4l2_std_id std_id;
74} adv7180_data;
75
76
77/*! List of input video formats supported. The video formats is corresponding
78 * with v4l2 id in video_fmt_t
79 */
80typedef enum {
81 ADV7180_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
82 ADV7180_PAL, /*!< (B, G, H, I, N)PAL video signal. */
83 ADV7180_NOT_LOCKED, /*!< Not locked on a signal. */
84} video_fmt_idx;
85
86/*! Number of video standards supported (including 'not locked' signal). */
87#define ADV7180_STD_MAX (ADV7180_PAL + 1)
88
89/*! Video format structure. */
90typedef struct {
91 int v4l2_id; /*!< Video for linux ID. */
92 char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
93 u16 raw_width; /*!< Raw width. */
94 u16 raw_height; /*!< Raw height. */
95 u16 active_width; /*!< Active width. */
96 u16 active_height; /*!< Active height. */
97} video_fmt_t;
98
99/*! Description of video formats supported.
100 *
101 * PAL: raw=720x625, active=720x576.
102 * NTSC: raw=720x525, active=720x480.
103 */
104static video_fmt_t video_fmts[] = {
105 { /*! NTSC */
106 .v4l2_id = V4L2_STD_NTSC,
107 .name = "NTSC",
108 .raw_width = 720, /* SENS_FRM_WIDTH */
109 .raw_height = 525, /* SENS_FRM_HEIGHT */
110 .active_width = 720, /* ACT_FRM_WIDTH plus 1 */
111 .active_height = 480, /* ACT_FRM_WIDTH plus 1 */
112 },
113 { /*! (B, G, H, I, N) PAL */
114 .v4l2_id = V4L2_STD_PAL,
115 .name = "PAL",
116 .raw_width = 720,
117 .raw_height = 625,
118 .active_width = 720,
119 .active_height = 576,
120 },
121 { /*! Unlocked standard */
122 .v4l2_id = V4L2_STD_ALL,
123 .name = "Autodetect",
124 .raw_width = 720,
125 .raw_height = 625,
126 .active_width = 720,
127 .active_height = 576,
128 },
129};
130
131/*!* Standard index of ADV7180. */
132static video_fmt_idx video_idx = ADV7180_PAL;
133
134/*! @brief This mutex is used to provide mutual exclusion.
135 *
136 * Create a mutex that can be used to provide mutually exclusive
137 * read/write access to the globally accessible data structures
138 * and variables that were defined above.
139 */
140static DEFINE_MUTEX(mutex);
141
142#define IF_NAME "adv7180"
143#define ADV7180_INPUT_CTL 0x00 /* Input Control */
144#define ADV7180_STATUS_1 0x10 /* Status #1 */
145#define ADV7180_BRIGHTNESS 0x0a /* Brightness */
146#define ADV7180_IDENT 0x11 /* IDENT */
147#define ADV7180_VSYNC_FIELD_CTL_1 0x31 /* VSYNC Field Control #1 */
148#define ADV7180_MANUAL_WIN_CTL 0x3d /* Manual Window Control */
149#define ADV7180_SD_SATURATION_CB 0xe3 /* SD Saturation Cb */
150#define ADV7180_SD_SATURATION_CR 0xe4 /* SD Saturation Cr */
151#define ADV7180_PWR_MNG 0x0f /* Power Management */
152
153/* supported controls */
154/* This hasn't been fully implemented yet.
155 * This is how it should work, though. */
156static struct v4l2_queryctrl adv7180_qctrl[] = {
157 {
158 .id = V4L2_CID_BRIGHTNESS,
159 .type = V4L2_CTRL_TYPE_INTEGER,
160 .name = "Brightness",
161 .minimum = 0, /* check this value */
162 .maximum = 255, /* check this value */
163 .step = 1, /* check this value */
164 .default_value = 127, /* check this value */
165 .flags = 0,
166 }, {
167 .id = V4L2_CID_SATURATION,
168 .type = V4L2_CTRL_TYPE_INTEGER,
169 .name = "Saturation",
170 .minimum = 0, /* check this value */
171 .maximum = 255, /* check this value */
172 .step = 0x1, /* check this value */
173 .default_value = 127, /* check this value */
174 .flags = 0,
175 }
176};
177
178static inline void adv7180_power_down(int enable)
179{
180 gpio_set_value_cansleep(pwn_gpio, !enable);
181 msleep(2);
182}
183
184static int adv7180_regulator_enable(struct device *dev)
185{
186 int ret = 0;
187
188 dvddio_regulator = devm_regulator_get(dev, "DOVDD");
189
190 if (!IS_ERR(dvddio_regulator)) {
191 regulator_set_voltage(dvddio_regulator,
192 ADV7180_VOLTAGE_DIGITAL_IO,
193 ADV7180_VOLTAGE_DIGITAL_IO);
194 ret = regulator_enable(dvddio_regulator);
195 if (ret) {
196 dev_err(dev, "set io voltage failed\n");
197 return ret;
198 } else {
199 dev_dbg(dev, "set io voltage ok\n");
200 }
201 } else {
202 dev_warn(dev, "cannot get io voltage\n");
203 }
204
205 dvdd_regulator = devm_regulator_get(dev, "DVDD");
206 if (!IS_ERR(dvdd_regulator)) {
207 regulator_set_voltage(dvdd_regulator,
208 ADV7180_VOLTAGE_DIGITAL_CORE,
209 ADV7180_VOLTAGE_DIGITAL_CORE);
210 ret = regulator_enable(dvdd_regulator);
211 if (ret) {
212 dev_err(dev, "set core voltage failed\n");
213 return ret;
214 } else {
215 dev_dbg(dev, "set core voltage ok\n");
216 }
217 } else {
218 dev_warn(dev, "cannot get core voltage\n");
219 }
220
221 avdd_regulator = devm_regulator_get(dev, "AVDD");
222 if (!IS_ERR(avdd_regulator)) {
223 regulator_set_voltage(avdd_regulator,
224 ADV7180_VOLTAGE_ANALOG,
225 ADV7180_VOLTAGE_ANALOG);
226 ret = regulator_enable(avdd_regulator);
227 if (ret) {
228 dev_err(dev, "set analog voltage failed\n");
229 return ret;
230 } else {
231 dev_dbg(dev, "set analog voltage ok\n");
232 }
233 } else {
234 dev_warn(dev, "cannot get analog voltage\n");
235 }
236
237 pvdd_regulator = devm_regulator_get(dev, "PVDD");
238 if (!IS_ERR(pvdd_regulator)) {
239 regulator_set_voltage(pvdd_regulator,
240 ADV7180_VOLTAGE_PLL,
241 ADV7180_VOLTAGE_PLL);
242 ret = regulator_enable(pvdd_regulator);
243 if (ret) {
244 dev_err(dev, "set pll voltage failed\n");
245 return ret;
246 } else {
247 dev_dbg(dev, "set pll voltage ok\n");
248 }
249 } else {
250 dev_warn(dev, "cannot get pll voltage\n");
251 }
252
253 return ret;
254}
255
256
257/***********************************************************************
258 * I2C transfert.
259 ***********************************************************************/
260
261/*! Read one register from a ADV7180 i2c slave device.
262 *
263 * @param *reg register in the device we wish to access.
264 *
265 * @return 0 if success, an error code otherwise.
266 */
267static inline int adv7180_read(u8 reg)
268{
269 int val;
270
271 val = i2c_smbus_read_byte_data(adv7180_data.sen.i2c_client, reg);
272 if (val < 0) {
273 dev_dbg(&adv7180_data.sen.i2c_client->dev,
274 "%s:read reg error: reg=%2x\n", __func__, reg);
275 return -1;
276 }
277 return val;
278}
279
280/*! Write one register of a ADV7180 i2c slave device.
281 *
282 * @param *reg register in the device we wish to access.
283 *
284 * @return 0 if success, an error code otherwise.
285 */
286static int adv7180_write_reg(u8 reg, u8 val)
287{
288 s32 ret;
289
290 ret = i2c_smbus_write_byte_data(adv7180_data.sen.i2c_client, reg, val);
291 if (ret < 0) {
292 dev_dbg(&adv7180_data.sen.i2c_client->dev,
293 "%s:write reg error:reg=%2x,val=%2x\n", __func__,
294 reg, val);
295 return -1;
296 }
297 return 0;
298}
299
300/***********************************************************************
301 * mxc_v4l2_capture interface.
302 ***********************************************************************/
303
304/*!
305 * Return attributes of current video standard.
306 * Since this device autodetects the current standard, this function also
307 * sets the values that need to be changed if the standard changes.
308 * There is no set std equivalent function.
309 *
310 * @return None.
311 */
312static void adv7180_get_std(v4l2_std_id *std)
313{
314 int tmp;
315 int idx;
316
317 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_get_std\n");
318
319 /* Read the AD_RESULT to get the detect output video standard */
320 tmp = adv7180_read(ADV7180_STATUS_1) & 0x70;
321
322 mutex_lock(&mutex);
323 if (tmp == 0x40) {
324 /* PAL */
325 *std = V4L2_STD_PAL;
326 idx = ADV7180_PAL;
327 } else if (tmp == 0) {
328 /*NTSC*/
329 *std = V4L2_STD_NTSC;
330 idx = ADV7180_NTSC;
331 } else {
332 *std = V4L2_STD_ALL;
333 idx = ADV7180_NOT_LOCKED;
334 dev_dbg(&adv7180_data.sen.i2c_client->dev,
335 "Got invalid video standard!\n");
336 }
337 mutex_unlock(&mutex);
338
339 /* This assumes autodetect which this device uses. */
340 if (*std != adv7180_data.std_id) {
341 video_idx = idx;
342 adv7180_data.std_id = *std;
343 adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
344 adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
345 }
346}
347
348/***********************************************************************
349 * IOCTL Functions from v4l2_int_ioctl_desc.
350 ***********************************************************************/
351
352/*!
353 * ioctl_g_ifparm - V4L2 sensor interface handler for vidioc_int_g_ifparm_num
354 * s: pointer to standard V4L2 device structure
355 * p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
356 *
357 * Gets slave interface parameters.
358 * Calculates the required xclk value to support the requested
359 * clock parameters in p. This value is returned in the p
360 * parameter.
361 *
362 * vidioc_int_g_ifparm returns platform-specific information about the
363 * interface settings used by the sensor.
364 *
365 * Called on open.
366 */
367static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
368{
369 dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_ifparm\n");
370
371 if (s == NULL) {
372 pr_err(" ERROR!! no slave device set!\n");
373 return -1;
374 }
375
376 /* Initialize structure to 0s then set any non-0 values. */
377 memset(p, 0, sizeof(*p));
378 p->if_type = V4L2_IF_TYPE_BT656; /* This is the only possibility. */
379 p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
380 p->u.bt656.nobt_hs_inv = 1;
381 p->u.bt656.bt_sync_correct = 1;
382
383 /* ADV7180 has a dedicated clock so no clock settings needed. */
384
385 return 0;
386}
387
388/*!
389 * Sets the camera power.
390 *
391 * s pointer to the camera device
392 * on if 1, power is to be turned on. 0 means power is to be turned off
393 *
394 * ioctl_s_power - V4L2 sensor interface handler for vidioc_int_s_power_num
395 * @s: pointer to standard V4L2 device structure
396 * @on: power state to which device is to be set
397 *
398 * Sets devices power state to requrested state, if possible.
399 * This is called on open, close, suspend and resume.
400 */
401static int ioctl_s_power(struct v4l2_int_device *s, int on)
402{
403 struct sensor *sensor = s->priv;
404
405 dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_s_power\n");
406
407 if (on && !sensor->sen.on) {
408 if (adv7180_write_reg(ADV7180_PWR_MNG, 0x04) != 0)
409 return -EIO;
410
411 /*
412 * FIXME:Additional 400ms to wait the chip to be stable?
413 * This is a workaround for preview scrolling issue.
414 */
415 msleep(400);
416 } else if (!on && sensor->sen.on) {
417 if (adv7180_write_reg(ADV7180_PWR_MNG, 0x24) != 0)
418 return -EIO;
419 }
420
421 sensor->sen.on = on;
422
423 return 0;
424}
425
426/*!
427 * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
428 * @s: pointer to standard V4L2 device structure
429 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
430 *
431 * Returns the sensor's video CAPTURE parameters.
432 */
433static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
434{
435 struct sensor *sensor = s->priv;
436 struct v4l2_captureparm *cparm = &a->parm.capture;
437
438 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_parm\n");
439
440 switch (a->type) {
441 /* These are all the possible cases. */
442 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
443 pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
444 memset(a, 0, sizeof(*a));
445 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
446 cparm->capability = sensor->sen.streamcap.capability;
447 cparm->timeperframe = sensor->sen.streamcap.timeperframe;
448 cparm->capturemode = sensor->sen.streamcap.capturemode;
449 break;
450
451 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
452 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
453 case V4L2_BUF_TYPE_VBI_CAPTURE:
454 case V4L2_BUF_TYPE_VBI_OUTPUT:
455 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
456 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
457 break;
458
459 default:
460 pr_debug("ioctl_g_parm:type is unknown %d\n", a->type);
461 break;
462 }
463
464 return 0;
465}
466
467/*!
468 * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
469 * @s: pointer to standard V4L2 device structure
470 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
471 *
472 * Configures the sensor to use the input parameters, if possible. If
473 * not possible, reverts to the old parameters and returns the
474 * appropriate error code.
475 *
476 * This driver cannot change these settings.
477 */
478static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
479{
480 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_parm\n");
481
482 switch (a->type) {
483 /* These are all the possible cases. */
484 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
485 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
486 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
487 case V4L2_BUF_TYPE_VBI_CAPTURE:
488 case V4L2_BUF_TYPE_VBI_OUTPUT:
489 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
490 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
491 break;
492
493 default:
494 pr_debug(" type is unknown - %d\n", a->type);
495 break;
496 }
497
498 return 0;
499}
500
501/*!
502 * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
503 * @s: pointer to standard V4L2 device structure
504 * @f: pointer to standard V4L2 v4l2_format structure
505 *
506 * Returns the sensor's current pixel format in the v4l2_format
507 * parameter.
508 */
509static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
510{
511 struct sensor *sensor = s->priv;
512
513 dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_g_fmt_cap\n");
514
515 switch (f->type) {
516 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
517 pr_debug(" Returning size of %dx%d\n",
518 sensor->sen.pix.width, sensor->sen.pix.height);
519 f->fmt.pix = sensor->sen.pix;
520 break;
521
522 case V4L2_BUF_TYPE_PRIVATE: {
523 v4l2_std_id std;
524 adv7180_get_std(&std);
525 f->fmt.pix.pixelformat = (u32)std;
526 }
527 break;
528
529 default:
530 f->fmt.pix = sensor->sen.pix;
531 break;
532 }
533
534 return 0;
535}
536
537/*!
538 * ioctl_queryctrl - V4L2 sensor interface handler for VIDIOC_QUERYCTRL ioctl
539 * @s: pointer to standard V4L2 device structure
540 * @qc: standard V4L2 VIDIOC_QUERYCTRL ioctl structure
541 *
542 * If the requested control is supported, returns the control information
543 * from the video_control[] array. Otherwise, returns -EINVAL if the
544 * control is not supported.
545 */
546static int ioctl_queryctrl(struct v4l2_int_device *s,
547 struct v4l2_queryctrl *qc)
548{
549 int i;
550
551 dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_queryctrl\n");
552
553 for (i = 0; i < ARRAY_SIZE(adv7180_qctrl); i++)
554 if (qc->id && qc->id == adv7180_qctrl[i].id) {
555 memcpy(qc, &(adv7180_qctrl[i]),
556 sizeof(*qc));
557 return 0;
558 }
559
560 return -EINVAL;
561}
562
563/*!
564 * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
565 * @s: pointer to standard V4L2 device structure
566 * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
567 *
568 * If the requested control is supported, returns the control's current
569 * value from the video_control[] array. Otherwise, returns -EINVAL
570 * if the control is not supported.
571 */
572static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
573{
574 int ret = 0;
575 int sat = 0;
576
577 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_g_ctrl\n");
578
579 switch (vc->id) {
580 case V4L2_CID_BRIGHTNESS:
581 dev_dbg(&adv7180_data.sen.i2c_client->dev,
582 " V4L2_CID_BRIGHTNESS\n");
583 adv7180_data.sen.brightness = adv7180_read(ADV7180_BRIGHTNESS);
584 vc->value = adv7180_data.sen.brightness;
585 break;
586 case V4L2_CID_CONTRAST:
587 dev_dbg(&adv7180_data.sen.i2c_client->dev,
588 " V4L2_CID_CONTRAST\n");
589 vc->value = adv7180_data.sen.contrast;
590 break;
591 case V4L2_CID_SATURATION:
592 dev_dbg(&adv7180_data.sen.i2c_client->dev,
593 " V4L2_CID_SATURATION\n");
594 sat = adv7180_read(ADV7180_SD_SATURATION_CB);
595 adv7180_data.sen.saturation = sat;
596 vc->value = adv7180_data.sen.saturation;
597 break;
598 case V4L2_CID_HUE:
599 dev_dbg(&adv7180_data.sen.i2c_client->dev,
600 " V4L2_CID_HUE\n");
601 vc->value = adv7180_data.sen.hue;
602 break;
603 case V4L2_CID_AUTO_WHITE_BALANCE:
604 dev_dbg(&adv7180_data.sen.i2c_client->dev,
605 " V4L2_CID_AUTO_WHITE_BALANCE\n");
606 break;
607 case V4L2_CID_DO_WHITE_BALANCE:
608 dev_dbg(&adv7180_data.sen.i2c_client->dev,
609 " V4L2_CID_DO_WHITE_BALANCE\n");
610 break;
611 case V4L2_CID_RED_BALANCE:
612 dev_dbg(&adv7180_data.sen.i2c_client->dev,
613 " V4L2_CID_RED_BALANCE\n");
614 vc->value = adv7180_data.sen.red;
615 break;
616 case V4L2_CID_BLUE_BALANCE:
617 dev_dbg(&adv7180_data.sen.i2c_client->dev,
618 " V4L2_CID_BLUE_BALANCE\n");
619 vc->value = adv7180_data.sen.blue;
620 break;
621 case V4L2_CID_GAMMA:
622 dev_dbg(&adv7180_data.sen.i2c_client->dev,
623 " V4L2_CID_GAMMA\n");
624 break;
625 case V4L2_CID_EXPOSURE:
626 dev_dbg(&adv7180_data.sen.i2c_client->dev,
627 " V4L2_CID_EXPOSURE\n");
628 vc->value = adv7180_data.sen.ae_mode;
629 break;
630 case V4L2_CID_AUTOGAIN:
631 dev_dbg(&adv7180_data.sen.i2c_client->dev,
632 " V4L2_CID_AUTOGAIN\n");
633 break;
634 case V4L2_CID_GAIN:
635 dev_dbg(&adv7180_data.sen.i2c_client->dev,
636 " V4L2_CID_GAIN\n");
637 break;
638 case V4L2_CID_HFLIP:
639 dev_dbg(&adv7180_data.sen.i2c_client->dev,
640 " V4L2_CID_HFLIP\n");
641 break;
642 case V4L2_CID_VFLIP:
643 dev_dbg(&adv7180_data.sen.i2c_client->dev,
644 " V4L2_CID_VFLIP\n");
645 break;
646 default:
647 dev_dbg(&adv7180_data.sen.i2c_client->dev,
648 " Default case\n");
649 vc->value = 0;
650 ret = -EPERM;
651 break;
652 }
653
654 return ret;
655}
656
657/*!
658 * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
659 * @s: pointer to standard V4L2 device structure
660 * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
661 *
662 * If the requested control is supported, sets the control's current
663 * value in HW (and updates the video_control[] array). Otherwise,
664 * returns -EINVAL if the control is not supported.
665 */
666static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
667{
668 int retval = 0;
669 u8 tmp;
670
671 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_s_ctrl\n");
672
673 switch (vc->id) {
674 case V4L2_CID_BRIGHTNESS:
675 dev_dbg(&adv7180_data.sen.i2c_client->dev,
676 " V4L2_CID_BRIGHTNESS\n");
677 tmp = vc->value;
678 adv7180_write_reg(ADV7180_BRIGHTNESS, tmp);
679 adv7180_data.sen.brightness = vc->value;
680 break;
681 case V4L2_CID_CONTRAST:
682 dev_dbg(&adv7180_data.sen.i2c_client->dev,
683 " V4L2_CID_CONTRAST\n");
684 break;
685 case V4L2_CID_SATURATION:
686 dev_dbg(&adv7180_data.sen.i2c_client->dev,
687 " V4L2_CID_SATURATION\n");
688 tmp = vc->value;
689 adv7180_write_reg(ADV7180_SD_SATURATION_CB, tmp);
690 adv7180_write_reg(ADV7180_SD_SATURATION_CR, tmp);
691 adv7180_data.sen.saturation = vc->value;
692 break;
693 case V4L2_CID_HUE:
694 dev_dbg(&adv7180_data.sen.i2c_client->dev,
695 " V4L2_CID_HUE\n");
696 break;
697 case V4L2_CID_AUTO_WHITE_BALANCE:
698 dev_dbg(&adv7180_data.sen.i2c_client->dev,
699 " V4L2_CID_AUTO_WHITE_BALANCE\n");
700 break;
701 case V4L2_CID_DO_WHITE_BALANCE:
702 dev_dbg(&adv7180_data.sen.i2c_client->dev,
703 " V4L2_CID_DO_WHITE_BALANCE\n");
704 break;
705 case V4L2_CID_RED_BALANCE:
706 dev_dbg(&adv7180_data.sen.i2c_client->dev,
707 " V4L2_CID_RED_BALANCE\n");
708 break;
709 case V4L2_CID_BLUE_BALANCE:
710 dev_dbg(&adv7180_data.sen.i2c_client->dev,
711 " V4L2_CID_BLUE_BALANCE\n");
712 break;
713 case V4L2_CID_GAMMA:
714 dev_dbg(&adv7180_data.sen.i2c_client->dev,
715 " V4L2_CID_GAMMA\n");
716 break;
717 case V4L2_CID_EXPOSURE:
718 dev_dbg(&adv7180_data.sen.i2c_client->dev,
719 " V4L2_CID_EXPOSURE\n");
720 break;
721 case V4L2_CID_AUTOGAIN:
722 dev_dbg(&adv7180_data.sen.i2c_client->dev,
723 " V4L2_CID_AUTOGAIN\n");
724 break;
725 case V4L2_CID_GAIN:
726 dev_dbg(&adv7180_data.sen.i2c_client->dev,
727 " V4L2_CID_GAIN\n");
728 break;
729 case V4L2_CID_HFLIP:
730 dev_dbg(&adv7180_data.sen.i2c_client->dev,
731 " V4L2_CID_HFLIP\n");
732 break;
733 case V4L2_CID_VFLIP:
734 dev_dbg(&adv7180_data.sen.i2c_client->dev,
735 " V4L2_CID_VFLIP\n");
736 break;
737 default:
738 dev_dbg(&adv7180_data.sen.i2c_client->dev,
739 " Default case\n");
740 retval = -EPERM;
741 break;
742 }
743
744 return retval;
745}
746
747/*!
748 * ioctl_enum_framesizes - V4L2 sensor interface handler for
749 * VIDIOC_ENUM_FRAMESIZES ioctl
750 * @s: pointer to standard V4L2 device structure
751 * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
752 *
753 * Return 0 if successful, otherwise -EINVAL.
754 */
755static int ioctl_enum_framesizes(struct v4l2_int_device *s,
756 struct v4l2_frmsizeenum *fsize)
757{
758 if (fsize->index >= 1)
759 return -EINVAL;
760
761 fsize->discrete.width = video_fmts[video_idx].active_width;
762 fsize->discrete.height = video_fmts[video_idx].active_height;
763
764 return 0;
765}
766
767/*!
768 * ioctl_g_chip_ident - V4L2 sensor interface handler for
769 * VIDIOC_DBG_G_CHIP_IDENT ioctl
770 * @s: pointer to standard V4L2 device structure
771 * @id: pointer to int
772 *
773 * Return 0.
774 */
775static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
776{
777 ((struct v4l2_dbg_chip_ident *)id)->match.type =
778 V4L2_CHIP_MATCH_I2C_DRIVER;
779 strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name,
780 "adv7180_decoder");
781 ((struct v4l2_dbg_chip_ident *)id)->ident = V4L2_IDENT_ADV7180;
782
783 return 0;
784}
785
786/*!
787 * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
788 * @s: pointer to standard V4L2 device structure
789 */
790static int ioctl_init(struct v4l2_int_device *s)
791{
792 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180:ioctl_init\n");
793 return 0;
794}
795
796/*!
797 * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
798 * @s: pointer to standard V4L2 device structure
799 *
800 * Initialise the device when slave attaches to the master.
801 */
802static int ioctl_dev_init(struct v4l2_int_device *s)
803{
804 dev_dbg(&adv7180_data.sen.i2c_client->dev, "adv7180:ioctl_dev_init\n");
805 return 0;
806}
807
808/*!
809 * This structure defines all the ioctls for this module.
810 */
811static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = {
812
813 {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*)ioctl_dev_init},
814
815 /*!
816 * Delinitialise the dev. at slave detach.
817 * The complement of ioctl_dev_init.
818 */
819/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */
820
821 {vidioc_int_s_power_num, (v4l2_int_ioctl_func*)ioctl_s_power},
822 {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*)ioctl_g_ifparm},
823/* {vidioc_int_g_needs_reset_num,
824 (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
825/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
826 {vidioc_int_init_num, (v4l2_int_ioctl_func*)ioctl_init},
827
828 /*!
829 * VIDIOC_ENUM_FMT ioctl for the CAPTURE buffer type.
830 */
831/* {vidioc_int_enum_fmt_cap_num,
832 (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */
833
834 /*!
835 * VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type.
836 * This ioctl is used to negotiate the image capture size and
837 * pixel format without actually making it take effect.
838 */
839/* {vidioc_int_try_fmt_cap_num,
840 (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
841
842 {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func*)ioctl_g_fmt_cap},
843
844 /*!
845 * If the requested format is supported, configures the HW to use that
846 * format, returns error code if format not supported or HW can't be
847 * correctly configured.
848 */
849/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */
850
851 {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm},
852 {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},
853 {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func*)ioctl_queryctrl},
854 {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func*)ioctl_g_ctrl},
855 {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},
856 {vidioc_int_enum_framesizes_num,
857 (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
858 {vidioc_int_g_chip_ident_num,
859 (v4l2_int_ioctl_func *)ioctl_g_chip_ident},
860};
861
862static struct v4l2_int_slave adv7180_slave = {
863 .ioctls = adv7180_ioctl_desc,
864 .num_ioctls = ARRAY_SIZE(adv7180_ioctl_desc),
865};
866
867static struct v4l2_int_device adv7180_int_device = {
868 .module = THIS_MODULE,
869 .name = "adv7180",
870 .type = v4l2_int_type_slave,
871 .u = {
872 .slave = &adv7180_slave,
873 },
874};
875
876
877/***********************************************************************
878 * I2C client and driver.
879 ***********************************************************************/
880
881/*! ADV7180 Reset function.
882 *
883 * @return None.
884 */
885static void adv7180_hard_reset(bool cvbs)
886{
887 dev_dbg(&adv7180_data.sen.i2c_client->dev,
888 "In adv7180:adv7180_hard_reset\n");
889
890 if (cvbs) {
891 /* Set CVBS input on AIN1 */
892 adv7180_write_reg(ADV7180_INPUT_CTL, 0x00);
893 } else {
894 /*
895 * Set YPbPr input on AIN1,4,5 and normal
896 * operations(autodection of all stds).
897 */
898 adv7180_write_reg(ADV7180_INPUT_CTL, 0x09);
899 }
900
901 /* Datasheet recommends */
902 adv7180_write_reg(0x01, 0xc8);
903 adv7180_write_reg(0x02, 0x04);
904 adv7180_write_reg(0x03, 0x00);
905 adv7180_write_reg(0x04, 0x45);
906 adv7180_write_reg(0x05, 0x00);
907 adv7180_write_reg(0x06, 0x02);
908 adv7180_write_reg(0x07, 0x7F);
909 adv7180_write_reg(0x08, 0x80);
910 adv7180_write_reg(0x0A, 0x00);
911 adv7180_write_reg(0x0B, 0x00);
912 adv7180_write_reg(0x0C, 0x36);
913 adv7180_write_reg(0x0D, 0x7C);
914 adv7180_write_reg(0x0E, 0x00);
915 adv7180_write_reg(0x0F, 0x00);
916 adv7180_write_reg(0x13, 0x00);
917 adv7180_write_reg(0x14, 0x12);
918 adv7180_write_reg(0x15, 0x00);
919 adv7180_write_reg(0x16, 0x00);
920 adv7180_write_reg(0x17, 0x01);
921 adv7180_write_reg(0x18, 0x93);
922 adv7180_write_reg(0xF1, 0x19);
923 adv7180_write_reg(0x1A, 0x00);
924 adv7180_write_reg(0x1B, 0x00);
925 adv7180_write_reg(0x1C, 0x00);
926 adv7180_write_reg(0x1D, 0x40);
927 adv7180_write_reg(0x1E, 0x00);
928 adv7180_write_reg(0x1F, 0x00);
929 adv7180_write_reg(0x20, 0x00);
930 adv7180_write_reg(0x21, 0x00);
931 adv7180_write_reg(0x22, 0x00);
932 adv7180_write_reg(0x23, 0xC0);
933 adv7180_write_reg(0x24, 0x00);
934 adv7180_write_reg(0x25, 0x00);
935 adv7180_write_reg(0x26, 0x00);
936 adv7180_write_reg(0x27, 0x58);
937 adv7180_write_reg(0x28, 0x00);
938 adv7180_write_reg(0x29, 0x00);
939 adv7180_write_reg(0x2A, 0x00);
940 adv7180_write_reg(0x2B, 0xE1);
941 adv7180_write_reg(0x2C, 0xAE);
942 adv7180_write_reg(0x2D, 0xF4);
943 adv7180_write_reg(0x2E, 0x00);
944 adv7180_write_reg(0x2F, 0xF0);
945 adv7180_write_reg(0x30, 0x00);
946 adv7180_write_reg(0x31, 0x12);
947 adv7180_write_reg(0x32, 0x41);
948 adv7180_write_reg(0x33, 0x84);
949 adv7180_write_reg(0x34, 0x00);
950 adv7180_write_reg(0x35, 0x02);
951 adv7180_write_reg(0x36, 0x00);
952 adv7180_write_reg(0x37, 0x01);
953 adv7180_write_reg(0x38, 0x80);
954 adv7180_write_reg(0x39, 0xC0);
955 adv7180_write_reg(0x3A, 0x10);
956 adv7180_write_reg(0x3B, 0x05);
957 adv7180_write_reg(0x3C, 0x58);
958 adv7180_write_reg(0x3D, 0xB2);
959 adv7180_write_reg(0x3E, 0x64);
960 adv7180_write_reg(0x3F, 0xE4);
961 adv7180_write_reg(0x40, 0x90);
962 adv7180_write_reg(0x41, 0x01);
963 adv7180_write_reg(0x42, 0x7E);
964 adv7180_write_reg(0x43, 0xA4);
965 adv7180_write_reg(0x44, 0xFF);
966 adv7180_write_reg(0x45, 0xB6);
967 adv7180_write_reg(0x46, 0x12);
968 adv7180_write_reg(0x48, 0x00);
969 adv7180_write_reg(0x49, 0x00);
970 adv7180_write_reg(0x4A, 0x00);
971 adv7180_write_reg(0x4B, 0x00);
972 adv7180_write_reg(0x4C, 0x00);
973 adv7180_write_reg(0x4D, 0xEF);
974 adv7180_write_reg(0x4E, 0x08);
975 adv7180_write_reg(0x4F, 0x08);
976 adv7180_write_reg(0x50, 0x08);
977 adv7180_write_reg(0x51, 0x24);
978 adv7180_write_reg(0x52, 0x0B);
979 adv7180_write_reg(0x53, 0x4E);
980 adv7180_write_reg(0x54, 0x80);
981 adv7180_write_reg(0x55, 0x00);
982 adv7180_write_reg(0x56, 0x10);
983 adv7180_write_reg(0x57, 0x00);
984 adv7180_write_reg(0x58, 0x00);
985 adv7180_write_reg(0x59, 0x00);
986 adv7180_write_reg(0x5A, 0x00);
987 adv7180_write_reg(0x5B, 0x00);
988 adv7180_write_reg(0x5C, 0x00);
989 adv7180_write_reg(0x5D, 0x00);
990 adv7180_write_reg(0x5E, 0x00);
991 adv7180_write_reg(0x5F, 0x00);
992 adv7180_write_reg(0x60, 0x00);
993 adv7180_write_reg(0x61, 0x00);
994 adv7180_write_reg(0x62, 0x20);
995 adv7180_write_reg(0x63, 0x00);
996 adv7180_write_reg(0x64, 0x00);
997 adv7180_write_reg(0x65, 0x00);
998 adv7180_write_reg(0x66, 0x00);
999 adv7180_write_reg(0x67, 0x03);
1000 adv7180_write_reg(0x68, 0x01);
1001 adv7180_write_reg(0x69, 0x00);
1002 adv7180_write_reg(0x6A, 0x00);
1003 adv7180_write_reg(0x6B, 0xC0);
1004 adv7180_write_reg(0x6C, 0x00);
1005 adv7180_write_reg(0x6D, 0x00);
1006 adv7180_write_reg(0x6E, 0x00);
1007 adv7180_write_reg(0x6F, 0x00);
1008 adv7180_write_reg(0x70, 0x00);
1009 adv7180_write_reg(0x71, 0x00);
1010 adv7180_write_reg(0x72, 0x00);
1011 adv7180_write_reg(0x73, 0x10);
1012 adv7180_write_reg(0x74, 0x04);
1013 adv7180_write_reg(0x75, 0x01);
1014 adv7180_write_reg(0x76, 0x00);
1015 adv7180_write_reg(0x77, 0x3F);
1016 adv7180_write_reg(0x78, 0xFF);
1017 adv7180_write_reg(0x79, 0xFF);
1018 adv7180_write_reg(0x7A, 0xFF);
1019 adv7180_write_reg(0x7B, 0x1E);
1020 adv7180_write_reg(0x7C, 0xC0);
1021 adv7180_write_reg(0x7D, 0x00);
1022 adv7180_write_reg(0x7E, 0x00);
1023 adv7180_write_reg(0x7F, 0x00);
1024 adv7180_write_reg(0x80, 0x00);
1025 adv7180_write_reg(0x81, 0xC0);
1026 adv7180_write_reg(0x82, 0x04);
1027 adv7180_write_reg(0x83, 0x00);
1028 adv7180_write_reg(0x84, 0x0C);
1029 adv7180_write_reg(0x85, 0x02);
1030 adv7180_write_reg(0x86, 0x03);
1031 adv7180_write_reg(0x87, 0x63);
1032 adv7180_write_reg(0x88, 0x5A);
1033 adv7180_write_reg(0x89, 0x08);
1034 adv7180_write_reg(0x8A, 0x10);
1035 adv7180_write_reg(0x8B, 0x00);
1036 adv7180_write_reg(0x8C, 0x40);
1037 adv7180_write_reg(0x8D, 0x00);
1038 adv7180_write_reg(0x8E, 0x40);
1039 adv7180_write_reg(0x8F, 0x00);
1040 adv7180_write_reg(0x90, 0x00);
1041 adv7180_write_reg(0x91, 0x50);
1042 adv7180_write_reg(0x92, 0x00);
1043 adv7180_write_reg(0x93, 0x00);
1044 adv7180_write_reg(0x94, 0x00);
1045 adv7180_write_reg(0x95, 0x00);
1046 adv7180_write_reg(0x96, 0x00);
1047 adv7180_write_reg(0x97, 0xF0);
1048 adv7180_write_reg(0x98, 0x00);
1049 adv7180_write_reg(0x99, 0x00);
1050 adv7180_write_reg(0x9A, 0x00);
1051 adv7180_write_reg(0x9B, 0x00);
1052 adv7180_write_reg(0x9C, 0x00);
1053 adv7180_write_reg(0x9D, 0x00);
1054 adv7180_write_reg(0x9E, 0x00);
1055 adv7180_write_reg(0x9F, 0x00);
1056 adv7180_write_reg(0xA0, 0x00);
1057 adv7180_write_reg(0xA1, 0x00);
1058 adv7180_write_reg(0xA2, 0x00);
1059 adv7180_write_reg(0xA3, 0x00);
1060 adv7180_write_reg(0xA4, 0x00);
1061 adv7180_write_reg(0xA5, 0x00);
1062 adv7180_write_reg(0xA6, 0x00);
1063 adv7180_write_reg(0xA7, 0x00);
1064 adv7180_write_reg(0xA8, 0x00);
1065 adv7180_write_reg(0xA9, 0x00);
1066 adv7180_write_reg(0xAA, 0x00);
1067 adv7180_write_reg(0xAB, 0x00);
1068 adv7180_write_reg(0xAC, 0x00);
1069 adv7180_write_reg(0xAD, 0x00);
1070 adv7180_write_reg(0xAE, 0x60);
1071 adv7180_write_reg(0xAF, 0x00);
1072 adv7180_write_reg(0xB0, 0x00);
1073 adv7180_write_reg(0xB1, 0x60);
1074 adv7180_write_reg(0xB2, 0x1C);
1075 adv7180_write_reg(0xB3, 0x54);
1076 adv7180_write_reg(0xB4, 0x00);
1077 adv7180_write_reg(0xB5, 0x00);
1078 adv7180_write_reg(0xB6, 0x00);
1079 adv7180_write_reg(0xB7, 0x13);
1080 adv7180_write_reg(0xB8, 0x03);
1081 adv7180_write_reg(0xB9, 0x33);
1082 adv7180_write_reg(0xBF, 0x02);
1083 adv7180_write_reg(0xC0, 0x00);
1084 adv7180_write_reg(0xC1, 0x00);
1085 adv7180_write_reg(0xC2, 0x00);
1086 adv7180_write_reg(0xC3, 0x00);
1087 adv7180_write_reg(0xC4, 0x00);
1088 adv7180_write_reg(0xC5, 0x81);
1089 adv7180_write_reg(0xC6, 0x00);
1090 adv7180_write_reg(0xC7, 0x00);
1091 adv7180_write_reg(0xC8, 0x00);
1092 adv7180_write_reg(0xC9, 0x04);
1093 adv7180_write_reg(0xCC, 0x69);
1094 adv7180_write_reg(0xCD, 0x00);
1095 adv7180_write_reg(0xCE, 0x01);
1096 adv7180_write_reg(0xCF, 0xB4);
1097 adv7180_write_reg(0xD0, 0x00);
1098 adv7180_write_reg(0xD1, 0x10);
1099 adv7180_write_reg(0xD2, 0xFF);
1100 adv7180_write_reg(0xD3, 0xFF);
1101 adv7180_write_reg(0xD4, 0x7F);
1102 adv7180_write_reg(0xD5, 0x7F);
1103 adv7180_write_reg(0xD6, 0x3E);
1104 adv7180_write_reg(0xD7, 0x08);
1105 adv7180_write_reg(0xD8, 0x3C);
1106 adv7180_write_reg(0xD9, 0x08);
1107 adv7180_write_reg(0xDA, 0x3C);
1108 adv7180_write_reg(0xDB, 0x9B);
1109 adv7180_write_reg(0xDC, 0xAC);
1110 adv7180_write_reg(0xDD, 0x4C);
1111 adv7180_write_reg(0xDE, 0x00);
1112 adv7180_write_reg(0xDF, 0x00);
1113 adv7180_write_reg(0xE0, 0x14);
1114 adv7180_write_reg(0xE1, 0x80);
1115 adv7180_write_reg(0xE2, 0x80);
1116 adv7180_write_reg(0xE3, 0x80);
1117 adv7180_write_reg(0xE4, 0x80);
1118 adv7180_write_reg(0xE5, 0x25);
1119 adv7180_write_reg(0xE6, 0x44);
1120 adv7180_write_reg(0xE7, 0x63);
1121 adv7180_write_reg(0xE8, 0x65);
1122 adv7180_write_reg(0xE9, 0x14);
1123 adv7180_write_reg(0xEA, 0x63);
1124 adv7180_write_reg(0xEB, 0x55);
1125 adv7180_write_reg(0xEC, 0x55);
1126 adv7180_write_reg(0xEE, 0x00);
1127 adv7180_write_reg(0xEF, 0x4A);
1128 adv7180_write_reg(0xF0, 0x44);
1129 adv7180_write_reg(0xF1, 0x0C);
1130 adv7180_write_reg(0xF2, 0x32);
1131 adv7180_write_reg(0xF3, 0x00);
1132 adv7180_write_reg(0xF4, 0x3F);
1133 adv7180_write_reg(0xF5, 0xE0);
1134 adv7180_write_reg(0xF6, 0x69);
1135 adv7180_write_reg(0xF7, 0x10);
1136 adv7180_write_reg(0xF8, 0x00);
1137 adv7180_write_reg(0xF9, 0x03);
1138 adv7180_write_reg(0xFA, 0xFA);
1139 adv7180_write_reg(0xFB, 0x40);
1140}
1141
1142/*! ADV7180 I2C attach function.
1143 *
1144 * @param *adapter struct i2c_adapter *.
1145 *
1146 * @return Error code indicating success or failure.
1147 */
1148
1149/*!
1150 * ADV7180 I2C probe function.
1151 * Function set in i2c_driver struct.
1152 * Called by insmod.
1153 *
1154 * @param *adapter I2C adapter descriptor.
1155 *
1156 * @return Error code indicating success or failure.
1157 */
1158static int adv7180_probe(struct i2c_client *client,
1159 const struct i2c_device_id *id)
1160{
1161 int rev_id;
1162 int ret = 0;
1163 u32 cvbs = true;
1164 struct pinctrl *pinctrl;
1165 struct device *dev = &client->dev;
1166
1167 printk(KERN_ERR"DBG sensor data is at %p\n", &adv7180_data);
1168
1169 /* ov5640 pinctrl */
1170 pinctrl = devm_pinctrl_get_select_default(dev);
1171 if (IS_ERR(pinctrl)) {
1172 dev_err(dev, "setup pinctrl failed\n");
1173 return PTR_ERR(pinctrl);
1174 }
1175
1176 /* request power down pin */
1177 pwn_gpio = of_get_named_gpio(dev->of_node, "pwn-gpios", 0);
1178 if (!gpio_is_valid(pwn_gpio)) {
1179 dev_err(dev, "no sensor pwdn pin available\n");
1180 return -ENODEV;
1181 }
1182 ret = devm_gpio_request_one(dev, pwn_gpio, GPIOF_OUT_INIT_HIGH,
1183 "adv7180_pwdn");
1184 if (ret < 0) {
1185 dev_err(dev, "no power pin available!\n");
1186 return ret;
1187 }
1188
1189 adv7180_regulator_enable(dev);
1190
1191 adv7180_power_down(0);
1192
1193 msleep(1);
1194
1195 /* Set initial values for the sensor struct. */
1196 memset(&adv7180_data, 0, sizeof(adv7180_data));
1197 adv7180_data.sen.i2c_client = client;
1198 adv7180_data.sen.streamcap.timeperframe.denominator = 30;
1199 adv7180_data.sen.streamcap.timeperframe.numerator = 1;
1200 adv7180_data.std_id = V4L2_STD_ALL;
1201 video_idx = ADV7180_NOT_LOCKED;
1202 adv7180_data.sen.pix.width = video_fmts[video_idx].raw_width;
1203 adv7180_data.sen.pix.height = video_fmts[video_idx].raw_height;
1204 adv7180_data.sen.pix.pixelformat = V4L2_PIX_FMT_UYVY; /* YUV422 */
1205 adv7180_data.sen.pix.priv = 1; /* 1 is used to indicate TV in */
1206 adv7180_data.sen.on = true;
1207
1208 adv7180_data.sen.sensor_clk = devm_clk_get(dev, "csi_mclk");
1209 if (IS_ERR(adv7180_data.sen.sensor_clk)) {
1210 dev_err(dev, "get mclk failed\n");
1211 return PTR_ERR(adv7180_data.sen.sensor_clk);
1212 }
1213
1214 ret = of_property_read_u32(dev->of_node, "mclk",
1215 &adv7180_data.sen.mclk);
1216 if (ret) {
1217 dev_err(dev, "mclk frequency is invalid\n");
1218 return ret;
1219 }
1220
1221 ret = of_property_read_u32(
1222 dev->of_node, "mclk_source",
1223 (u32 *) &(adv7180_data.sen.mclk_source));
1224 if (ret) {
1225 dev_err(dev, "mclk_source invalid\n");
1226 return ret;
1227 }
1228
1229 ret = of_property_read_u32(dev->of_node, "csi_id",
1230 &(adv7180_data.sen.csi));
1231 if (ret) {
1232 dev_err(dev, "csi_id invalid\n");
1233 return ret;
1234 }
1235
1236 clk_prepare_enable(adv7180_data.sen.sensor_clk);
1237
1238 dev_dbg(&adv7180_data.sen.i2c_client->dev,
1239 "%s:adv7180 probe i2c address is 0x%02X\n",
1240 __func__, adv7180_data.sen.i2c_client->addr);
1241
1242 /*! Read the revision ID of the tvin chip */
1243 rev_id = adv7180_read(ADV7180_IDENT);
1244 dev_dbg(dev,
1245 "%s:Analog Device adv7%2X0 detected!\n", __func__,
1246 rev_id);
1247
1248 ret = of_property_read_u32(dev->of_node, "cvbs", &(cvbs));
1249 if (ret) {
1250 dev_err(dev, "cvbs setting is not found\n");
1251 cvbs = true;
1252 }
1253
1254 /*! ADV7180 initialization. */
1255 adv7180_hard_reset(cvbs);
1256
1257 pr_debug(" type is %d (expect %d)\n",
1258 adv7180_int_device.type, v4l2_int_type_slave);
1259 pr_debug(" num ioctls is %d\n",
1260 adv7180_int_device.u.slave->num_ioctls);
1261
1262 /* This function attaches this structure to the /dev/video0 device.
1263 * The pointer in priv points to the adv7180_data structure here.*/
1264 adv7180_int_device.priv = &adv7180_data;
1265 ret = v4l2_int_device_register(&adv7180_int_device);
1266
1267 clk_disable_unprepare(adv7180_data.sen.sensor_clk);
1268
1269 return ret;
1270}
1271
1272/*!
1273 * ADV7180 I2C detach function.
1274 * Called on rmmod.
1275 *
1276 * @param *client struct i2c_client*.
1277 *
1278 * @return Error code indicating success or failure.
1279 */
1280static int adv7180_detach(struct i2c_client *client)
1281{
1282 dev_dbg(&adv7180_data.sen.i2c_client->dev,
1283 "%s:Removing %s video decoder @ 0x%02X from adapter %s\n",
1284 __func__, IF_NAME, client->addr << 1, client->adapter->name);
1285
1286 /* Power down via i2c */
1287 adv7180_write_reg(ADV7180_PWR_MNG, 0x24);
1288
1289 if (dvddio_regulator)
1290 regulator_disable(dvddio_regulator);
1291
1292 if (dvdd_regulator)
1293 regulator_disable(dvdd_regulator);
1294
1295 if (avdd_regulator)
1296 regulator_disable(avdd_regulator);
1297
1298 if (pvdd_regulator)
1299 regulator_disable(pvdd_regulator);
1300
1301 v4l2_int_device_unregister(&adv7180_int_device);
1302
1303 return 0;
1304}
1305
1306/*!
1307 * ADV7180 init function.
1308 * Called on insmod.
1309 *
1310 * @return Error code indicating success or failure.
1311 */
1312static __init int adv7180_init(void)
1313{
1314 u8 err = 0;
1315
1316 pr_debug("In adv7180_init\n");
1317
1318 /* Tells the i2c driver what functions to call for this driver. */
1319 err = i2c_add_driver(&adv7180_i2c_driver);
1320 if (err != 0)
1321 pr_err("%s:driver registration failed, error=%d\n",
1322 __func__, err);
1323
1324 return err;
1325}
1326
1327/*!
1328 * ADV7180 cleanup function.
1329 * Called on rmmod.
1330 *
1331 * @return Error code indicating success or failure.
1332 */
1333static void __exit adv7180_clean(void)
1334{
1335 dev_dbg(&adv7180_data.sen.i2c_client->dev, "In adv7180_clean\n");
1336 i2c_del_driver(&adv7180_i2c_driver);
1337}
1338
1339module_init(adv7180_init);
1340module_exit(adv7180_clean);
1341
1342MODULE_AUTHOR("Freescale Semiconductor");
1343MODULE_DESCRIPTION("Anolog Device ADV7180 video decoder driver");
1344MODULE_LICENSE("GPL");