[media] adv7180: Reset the device before initialization
[deliverable/linux.git] / drivers / media / i2c / adv7180.c
CommitLineData
6789cb52
RR
1/*
2 * adv7180.c Analog Devices ADV7180 video decoder driver
3 * Copyright (c) 2009 Intel Corporation
cccb83f7
VB
4 * Copyright (C) 2013 Cogent Embedded, Inc.
5 * Copyright (C) 2013 Renesas Solutions Corp.
6789cb52
RR
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/errno.h>
24#include <linux/kernel.h>
25#include <linux/interrupt.h>
26#include <linux/i2c.h>
5a0e3ad6 27#include <linux/slab.h>
6789cb52
RR
28#include <media/v4l2-ioctl.h>
29#include <linux/videodev2.h>
30#include <media/v4l2-device.h>
c9fbeddd 31#include <media/v4l2-ctrls.h>
42752f7a 32#include <linux/mutex.h>
c18818e9 33#include <linux/delay.h>
6789cb52 34
3999e5d0 35#define ADV7180_REG_INPUT_CONTROL 0x0000
d3124294
RR
36#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM 0x00
37#define ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM_PED 0x10
38#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_J_SECAM 0x20
39#define ADV7180_INPUT_CONTROL_AD_PAL_N_NTSC_M_SECAM 0x30
40#define ADV7180_INPUT_CONTROL_NTSC_J 0x40
41#define ADV7180_INPUT_CONTROL_NTSC_M 0x50
42#define ADV7180_INPUT_CONTROL_PAL60 0x60
43#define ADV7180_INPUT_CONTROL_NTSC_443 0x70
44#define ADV7180_INPUT_CONTROL_PAL_BG 0x80
45#define ADV7180_INPUT_CONTROL_PAL_N 0x90
46#define ADV7180_INPUT_CONTROL_PAL_M 0xa0
47#define ADV7180_INPUT_CONTROL_PAL_M_PED 0xb0
48#define ADV7180_INPUT_CONTROL_PAL_COMB_N 0xc0
49#define ADV7180_INPUT_CONTROL_PAL_COMB_N_PED 0xd0
50#define ADV7180_INPUT_CONTROL_PAL_SECAM 0xe0
51#define ADV7180_INPUT_CONTROL_PAL_SECAM_PED 0xf0
bca7ad1a 52#define ADV7180_INPUT_CONTROL_INSEL_MASK 0x0f
d3124294 53
3999e5d0 54#define ADV7180_REG_EXTENDED_OUTPUT_CONTROL 0x0004
42752f7a 55#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
6789cb52 56
029d6177 57#define ADV7180_REG_AUTODETECT_ENABLE 0x07
42752f7a 58#define ADV7180_AUTODETECT_DEFAULT 0x7f
c9fbeddd 59/* Contrast */
3999e5d0 60#define ADV7180_REG_CON 0x0008 /*Unsigned */
c9fbeddd
FV
61#define ADV7180_CON_MIN 0
62#define ADV7180_CON_DEF 128
63#define ADV7180_CON_MAX 255
64/* Brightness*/
3999e5d0 65#define ADV7180_REG_BRI 0x000a /*Signed */
c9fbeddd
FV
66#define ADV7180_BRI_MIN -128
67#define ADV7180_BRI_DEF 0
68#define ADV7180_BRI_MAX 127
69/* Hue */
3999e5d0 70#define ADV7180_REG_HUE 0x000b /*Signed, inverted */
c9fbeddd
FV
71#define ADV7180_HUE_MIN -127
72#define ADV7180_HUE_DEF 0
73#define ADV7180_HUE_MAX 128
bca7ad1a 74
3999e5d0 75#define ADV7180_REG_CTRL 0x000e
029d6177 76#define ADV7180_CTRL_IRQ_SPACE 0x20
6789cb52 77
029d6177 78#define ADV7180_REG_PWR_MAN 0x0f
bca7ad1a
FV
79#define ADV7180_PWR_MAN_ON 0x04
80#define ADV7180_PWR_MAN_OFF 0x24
81#define ADV7180_PWR_MAN_RES 0x80
82
3999e5d0 83#define ADV7180_REG_STATUS1 0x0010
d3124294
RR
84#define ADV7180_STATUS1_IN_LOCK 0x01
85#define ADV7180_STATUS1_AUTOD_MASK 0x70
6789cb52
RR
86#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
87#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
88#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
89#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
90#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
91#define ADV7180_STATUS1_AUTOD_SECAM 0x50
92#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
93#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
94
3999e5d0 95#define ADV7180_REG_IDENT 0x0011
6789cb52
RR
96#define ADV7180_ID_7180 0x18
97
3999e5d0 98#define ADV7180_REG_ICONF1 0x0040
42752f7a
RR
99#define ADV7180_ICONF1_ACTIVE_LOW 0x01
100#define ADV7180_ICONF1_PSYNC_ONLY 0x10
101#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
c9fbeddd 102/* Saturation */
3999e5d0
LPC
103#define ADV7180_REG_SD_SAT_CB 0x00e3 /*Unsigned */
104#define ADV7180_REG_SD_SAT_CR 0x00e4 /*Unsigned */
c9fbeddd
FV
105#define ADV7180_SAT_MIN 0
106#define ADV7180_SAT_DEF 128
107#define ADV7180_SAT_MAX 255
bca7ad1a 108
42752f7a
RR
109#define ADV7180_IRQ1_LOCK 0x01
110#define ADV7180_IRQ1_UNLOCK 0x02
3999e5d0
LPC
111#define ADV7180_REG_ISR1 0x0042
112#define ADV7180_REG_ICR1 0x0043
113#define ADV7180_REG_IMR1 0x0044
114#define ADV7180_REG_IMR2 0x0048
42752f7a 115#define ADV7180_IRQ3_AD_CHANGE 0x08
3999e5d0
LPC
116#define ADV7180_REG_ISR3 0x004A
117#define ADV7180_REG_ICR3 0x004B
118#define ADV7180_REG_IMR3 0x004C
029d6177 119#define ADV7180_REG_IMR4 0x50
6789cb52 120
3999e5d0 121#define ADV7180_REG_NTSC_V_BIT_END 0x00E6
bca7ad1a
FV
122#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F
123
6789cb52 124struct adv7180_state {
c9fbeddd 125 struct v4l2_ctrl_handler ctrl_hdl;
c277b60a 126 struct v4l2_subdev sd;
42752f7a
RR
127 struct mutex mutex; /* mutual excl. when accessing chip */
128 int irq;
c277b60a
RR
129 v4l2_std_id curr_norm;
130 bool autodetect;
e246c333 131 bool powered;
bca7ad1a 132 u8 input;
3999e5d0
LPC
133
134 struct i2c_client *client;
135 unsigned int register_page;
6789cb52 136};
c9fbeddd
FV
137#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
138 struct adv7180_state, \
139 ctrl_hdl)->sd)
6789cb52 140
3999e5d0
LPC
141static int adv7180_select_page(struct adv7180_state *state, unsigned int page)
142{
143 if (state->register_page != page) {
144 i2c_smbus_write_byte_data(state->client, ADV7180_REG_CTRL,
145 page);
146 state->register_page = page;
147 }
148
149 return 0;
150}
151
152static int adv7180_write(struct adv7180_state *state, unsigned int reg,
153 unsigned int value)
154{
155 lockdep_assert_held(&state->mutex);
156 adv7180_select_page(state, reg >> 8);
157 return i2c_smbus_write_byte_data(state->client, reg & 0xff, value);
158}
159
160static int adv7180_read(struct adv7180_state *state, unsigned int reg)
161{
162 lockdep_assert_held(&state->mutex);
163 adv7180_select_page(state, reg >> 8);
164 return i2c_smbus_read_byte_data(state->client, reg & 0xff);
165}
166
167
d3124294 168static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
6789cb52 169{
b294a192
VB
170 /* in case V4L2_IN_ST_NO_SIGNAL */
171 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
172 return V4L2_STD_UNKNOWN;
173
6789cb52
RR
174 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
175 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
d3124294 176 return V4L2_STD_NTSC;
6789cb52
RR
177 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
178 return V4L2_STD_NTSC_443;
179 case ADV7180_STATUS1_AUTOD_PAL_M:
180 return V4L2_STD_PAL_M;
181 case ADV7180_STATUS1_AUTOD_PAL_60:
182 return V4L2_STD_PAL_60;
183 case ADV7180_STATUS1_AUTOD_PAL_B_G:
184 return V4L2_STD_PAL;
185 case ADV7180_STATUS1_AUTOD_SECAM:
186 return V4L2_STD_SECAM;
187 case ADV7180_STATUS1_AUTOD_PAL_COMB:
188 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
189 case ADV7180_STATUS1_AUTOD_SECAM_525:
190 return V4L2_STD_SECAM;
191 default:
192 return V4L2_STD_UNKNOWN;
193 }
194}
195
c277b60a
RR
196static int v4l2_std_to_adv7180(v4l2_std_id std)
197{
198 if (std == V4L2_STD_PAL_60)
199 return ADV7180_INPUT_CONTROL_PAL60;
200 if (std == V4L2_STD_NTSC_443)
201 return ADV7180_INPUT_CONTROL_NTSC_443;
202 if (std == V4L2_STD_PAL_N)
203 return ADV7180_INPUT_CONTROL_PAL_N;
204 if (std == V4L2_STD_PAL_M)
205 return ADV7180_INPUT_CONTROL_PAL_M;
206 if (std == V4L2_STD_PAL_Nc)
207 return ADV7180_INPUT_CONTROL_PAL_COMB_N;
208
209 if (std & V4L2_STD_PAL)
210 return ADV7180_INPUT_CONTROL_PAL_BG;
211 if (std & V4L2_STD_NTSC)
212 return ADV7180_INPUT_CONTROL_NTSC_M;
213 if (std & V4L2_STD_SECAM)
214 return ADV7180_INPUT_CONTROL_PAL_SECAM;
215
216 return -EINVAL;
217}
218
d3124294
RR
219static u32 adv7180_status_to_v4l2(u8 status1)
220{
221 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
222 return V4L2_IN_ST_NO_SIGNAL;
223
224 return 0;
225}
226
3999e5d0 227static int __adv7180_status(struct adv7180_state *state, u32 *status,
bca7ad1a 228 v4l2_std_id *std)
d3124294 229{
3999e5d0 230 int status1 = adv7180_read(state, ADV7180_REG_STATUS1);
d3124294
RR
231
232 if (status1 < 0)
233 return status1;
234
235 if (status)
236 *status = adv7180_status_to_v4l2(status1);
237 if (std)
238 *std = adv7180_std_to_v4l2(status1);
239
240 return 0;
241}
242
6789cb52
RR
243static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
244{
245 return container_of(sd, struct adv7180_state, sd);
246}
247
248static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
249{
c277b60a 250 struct adv7180_state *state = to_state(sd);
42752f7a
RR
251 int err = mutex_lock_interruptible(&state->mutex);
252 if (err)
253 return err;
c277b60a 254
42752f7a
RR
255 /* when we are interrupt driven we know the state */
256 if (!state->autodetect || state->irq > 0)
c277b60a
RR
257 *std = state->curr_norm;
258 else
3999e5d0 259 err = __adv7180_status(state, NULL, std);
c277b60a 260
42752f7a 261 mutex_unlock(&state->mutex);
c277b60a 262 return err;
d3124294 263}
6789cb52 264
bca7ad1a
FV
265static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
266 u32 output, u32 config)
267{
268 struct adv7180_state *state = to_state(sd);
269 int ret = mutex_lock_interruptible(&state->mutex);
bca7ad1a
FV
270
271 if (ret)
272 return ret;
273
c9fbeddd 274 /* We cannot discriminate between LQFP and 40-pin LFCSP, so accept
bca7ad1a
FV
275 * all inputs and let the card driver take care of validation
276 */
277 if ((input & ADV7180_INPUT_CONTROL_INSEL_MASK) != input)
278 goto out;
279
3999e5d0 280 ret = adv7180_read(state, ADV7180_REG_INPUT_CONTROL);
bca7ad1a
FV
281 if (ret < 0)
282 goto out;
283
284 ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
3999e5d0 285 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL, ret | input);
bca7ad1a
FV
286 state->input = input;
287out:
288 mutex_unlock(&state->mutex);
289 return ret;
290}
291
d3124294
RR
292static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
293{
42752f7a
RR
294 struct adv7180_state *state = to_state(sd);
295 int ret = mutex_lock_interruptible(&state->mutex);
296 if (ret)
297 return ret;
298
3999e5d0 299 ret = __adv7180_status(state, status, NULL);
42752f7a
RR
300 mutex_unlock(&state->mutex);
301 return ret;
6789cb52
RR
302}
303
c277b60a
RR
304static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
305{
306 struct adv7180_state *state = to_state(sd);
42752f7a
RR
307 int ret = mutex_lock_interruptible(&state->mutex);
308 if (ret)
309 return ret;
c277b60a
RR
310
311 /* all standards -> autodetect */
312 if (std == V4L2_STD_ALL) {
3999e5d0
LPC
313 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
314 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
315 | state->input);
c277b60a
RR
316 if (ret < 0)
317 goto out;
318
3999e5d0 319 __adv7180_status(state, NULL, &state->curr_norm);
c277b60a
RR
320 state->autodetect = true;
321 } else {
322 ret = v4l2_std_to_adv7180(std);
323 if (ret < 0)
324 goto out;
325
3999e5d0
LPC
326 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
327 ret | state->input);
c277b60a
RR
328 if (ret < 0)
329 goto out;
330
331 state->curr_norm = std;
332 state->autodetect = false;
333 }
334 ret = 0;
335out:
42752f7a 336 mutex_unlock(&state->mutex);
c277b60a
RR
337 return ret;
338}
339
3999e5d0 340static int adv7180_set_power(struct adv7180_state *state, bool on)
e246c333
LPC
341{
342 u8 val;
343
344 if (on)
345 val = ADV7180_PWR_MAN_ON;
346 else
347 val = ADV7180_PWR_MAN_OFF;
348
3999e5d0 349 return adv7180_write(state, ADV7180_REG_PWR_MAN, val);
e246c333
LPC
350}
351
352static int adv7180_s_power(struct v4l2_subdev *sd, int on)
353{
354 struct adv7180_state *state = to_state(sd);
e246c333
LPC
355 int ret;
356
357 ret = mutex_lock_interruptible(&state->mutex);
358 if (ret)
359 return ret;
360
3999e5d0 361 ret = adv7180_set_power(state, on);
e246c333
LPC
362 if (ret == 0)
363 state->powered = on;
364
365 mutex_unlock(&state->mutex);
366 return ret;
367}
368
c9fbeddd 369static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
bca7ad1a 370{
c9fbeddd 371 struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
bca7ad1a 372 struct adv7180_state *state = to_state(sd);
bca7ad1a 373 int ret = mutex_lock_interruptible(&state->mutex);
c9fbeddd
FV
374 int val;
375
bca7ad1a
FV
376 if (ret)
377 return ret;
c9fbeddd 378 val = ctrl->val;
bca7ad1a
FV
379 switch (ctrl->id) {
380 case V4L2_CID_BRIGHTNESS:
3999e5d0 381 ret = adv7180_write(state, ADV7180_REG_BRI, val);
bca7ad1a
FV
382 break;
383 case V4L2_CID_HUE:
bca7ad1a 384 /*Hue is inverted according to HSL chart */
3999e5d0 385 ret = adv7180_write(state, ADV7180_REG_HUE, -val);
bca7ad1a
FV
386 break;
387 case V4L2_CID_CONTRAST:
3999e5d0 388 ret = adv7180_write(state, ADV7180_REG_CON, val);
bca7ad1a
FV
389 break;
390 case V4L2_CID_SATURATION:
bca7ad1a
FV
391 /*
392 *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
393 *Let's not confuse the user, everybody understands saturation
394 */
3999e5d0 395 ret = adv7180_write(state, ADV7180_REG_SD_SAT_CB, val);
bca7ad1a
FV
396 if (ret < 0)
397 break;
3999e5d0 398 ret = adv7180_write(state, ADV7180_REG_SD_SAT_CR, val);
bca7ad1a
FV
399 break;
400 default:
401 ret = -EINVAL;
402 }
403
404 mutex_unlock(&state->mutex);
405 return ret;
406}
407
c9fbeddd
FV
408static const struct v4l2_ctrl_ops adv7180_ctrl_ops = {
409 .s_ctrl = adv7180_s_ctrl,
410};
411
412static int adv7180_init_controls(struct adv7180_state *state)
413{
414 v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
415
416 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
417 V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
418 ADV7180_BRI_MAX, 1, ADV7180_BRI_DEF);
419 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
420 V4L2_CID_CONTRAST, ADV7180_CON_MIN,
421 ADV7180_CON_MAX, 1, ADV7180_CON_DEF);
422 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
423 V4L2_CID_SATURATION, ADV7180_SAT_MIN,
424 ADV7180_SAT_MAX, 1, ADV7180_SAT_DEF);
425 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
426 V4L2_CID_HUE, ADV7180_HUE_MIN,
427 ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF);
428 state->sd.ctrl_handler = &state->ctrl_hdl;
429 if (state->ctrl_hdl.error) {
430 int err = state->ctrl_hdl.error;
431
432 v4l2_ctrl_handler_free(&state->ctrl_hdl);
433 return err;
434 }
435 v4l2_ctrl_handler_setup(&state->ctrl_hdl);
436
437 return 0;
438}
439static void adv7180_exit_controls(struct adv7180_state *state)
440{
441 v4l2_ctrl_handler_free(&state->ctrl_hdl);
442}
443
cccb83f7 444static int adv7180_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
f5fe58fd 445 u32 *code)
cccb83f7
VB
446{
447 if (index > 0)
448 return -EINVAL;
449
f5fe58fd 450 *code = MEDIA_BUS_FMT_YUYV8_2X8;
cccb83f7
VB
451
452 return 0;
453}
454
455static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
456 struct v4l2_mbus_framefmt *fmt)
457{
458 struct adv7180_state *state = to_state(sd);
459
f5fe58fd 460 fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
cccb83f7
VB
461 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
462 fmt->field = V4L2_FIELD_INTERLACED;
463 fmt->width = 720;
464 fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
465
466 return 0;
467}
468
469static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
470 struct v4l2_mbus_config *cfg)
471{
472 /*
473 * The ADV7180 sensor supports BT.601/656 output modes.
474 * The BT.656 is default and not yet configurable by s/w.
475 */
476 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
477 V4L2_MBUS_DATA_ACTIVE_HIGH;
478 cfg->type = V4L2_MBUS_BT656;
479
480 return 0;
481}
482
6789cb52 483static const struct v4l2_subdev_video_ops adv7180_video_ops = {
8774bed9 484 .s_std = adv7180_s_std,
6789cb52 485 .querystd = adv7180_querystd,
d3124294 486 .g_input_status = adv7180_g_input_status,
bca7ad1a 487 .s_routing = adv7180_s_routing,
cccb83f7
VB
488 .enum_mbus_fmt = adv7180_enum_mbus_fmt,
489 .try_mbus_fmt = adv7180_mbus_fmt,
490 .g_mbus_fmt = adv7180_mbus_fmt,
491 .s_mbus_fmt = adv7180_mbus_fmt,
492 .g_mbus_config = adv7180_g_mbus_config,
6789cb52
RR
493};
494
495static const struct v4l2_subdev_core_ops adv7180_core_ops = {
e246c333 496 .s_power = adv7180_s_power,
6789cb52
RR
497};
498
499static const struct v4l2_subdev_ops adv7180_ops = {
500 .core = &adv7180_core_ops,
501 .video = &adv7180_video_ops,
502};
503
0c25534d 504static irqreturn_t adv7180_irq(int irq, void *devid)
42752f7a 505{
0c25534d 506 struct adv7180_state *state = devid;
42752f7a
RR
507 u8 isr3;
508
509 mutex_lock(&state->mutex);
3999e5d0 510 isr3 = adv7180_read(state, ADV7180_REG_ISR3);
42752f7a 511 /* clear */
3999e5d0 512 adv7180_write(state, ADV7180_REG_ICR3, isr3);
42752f7a
RR
513
514 if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
3999e5d0 515 __adv7180_status(state, NULL, &state->curr_norm);
42752f7a
RR
516 mutex_unlock(&state->mutex);
517
42752f7a
RR
518 return IRQ_HANDLED;
519}
520
3999e5d0 521static int init_device(struct adv7180_state *state)
6789cb52 522{
6789cb52
RR
523 int ret;
524
3999e5d0
LPC
525 mutex_lock(&state->mutex);
526
c18818e9
LPC
527 adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
528 usleep_range(2000, 10000);
529
6789cb52 530 /* Initialize adv7180 */
42752f7a 531 /* Enable autodetection */
bca7ad1a 532 if (state->autodetect) {
3999e5d0 533 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
bca7ad1a
FV
534 ADV7180_INPUT_CONTROL_AD_PAL_BG_NTSC_J_SECAM
535 | state->input);
536 if (ret < 0)
3999e5d0 537 goto out_unlock;
42752f7a 538
3999e5d0 539 ret = adv7180_write(state, ADV7180_REG_AUTODETECT_ENABLE,
bca7ad1a
FV
540 ADV7180_AUTODETECT_DEFAULT);
541 if (ret < 0)
3999e5d0 542 goto out_unlock;
bca7ad1a
FV
543 } else {
544 ret = v4l2_std_to_adv7180(state->curr_norm);
545 if (ret < 0)
3999e5d0 546 goto out_unlock;
42752f7a 547
3999e5d0 548 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
bca7ad1a
FV
549 ret | state->input);
550 if (ret < 0)
3999e5d0 551 goto out_unlock;
bca7ad1a
FV
552
553 }
42752f7a 554 /* ITU-R BT.656-4 compatible */
3999e5d0 555 ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
bca7ad1a 556 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
42752f7a 557 if (ret < 0)
3999e5d0 558 goto out_unlock;
bca7ad1a
FV
559
560 /* Manually set V bit end position in NTSC mode */
3999e5d0 561 ret = adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
bca7ad1a
FV
562 ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
563 if (ret < 0)
3999e5d0 564 goto out_unlock;
42752f7a
RR
565
566 /* read current norm */
3999e5d0 567 __adv7180_status(state, NULL, &state->curr_norm);
42752f7a
RR
568
569 /* register for interrupts */
570 if (state->irq > 0) {
42752f7a 571 /* config the Interrupt pin to be active low */
3999e5d0 572 ret = adv7180_write(state, ADV7180_REG_ICONF1,
bca7ad1a
FV
573 ADV7180_ICONF1_ACTIVE_LOW |
574 ADV7180_ICONF1_PSYNC_ONLY);
42752f7a 575 if (ret < 0)
3999e5d0 576 goto out_unlock;
42752f7a 577
3999e5d0 578 ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
42752f7a 579 if (ret < 0)
3999e5d0 580 goto out_unlock;
42752f7a 581
3999e5d0 582 ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
42752f7a 583 if (ret < 0)
3999e5d0 584 goto out_unlock;
42752f7a
RR
585
586 /* enable AD change interrupts interrupts */
3999e5d0 587 ret = adv7180_write(state, ADV7180_REG_IMR3,
bca7ad1a 588 ADV7180_IRQ3_AD_CHANGE);
42752f7a 589 if (ret < 0)
3999e5d0 590 goto out_unlock;
42752f7a 591
3999e5d0 592 ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
42752f7a 593 if (ret < 0)
3999e5d0 594 goto out_unlock;
6789cb52
RR
595 }
596
3999e5d0
LPC
597out_unlock:
598 mutex_unlock(&state->mutex);
df065b37 599
df065b37 600 return ret;
bca7ad1a
FV
601}
602
4c62e976
GKH
603static int adv7180_probe(struct i2c_client *client,
604 const struct i2c_device_id *id)
bca7ad1a
FV
605{
606 struct adv7180_state *state;
607 struct v4l2_subdev *sd;
608 int ret;
609
610 /* Check if the adapter supports the needed features */
611 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
612 return -EIO;
613
614 v4l_info(client, "chip found @ 0x%02x (%s)\n",
615 client->addr, client->adapter->name);
616
c02b211d 617 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
7657e064
FE
618 if (state == NULL)
619 return -ENOMEM;
bca7ad1a 620
3999e5d0
LPC
621 state->client = client;
622
bca7ad1a 623 state->irq = client->irq;
bca7ad1a
FV
624 mutex_init(&state->mutex);
625 state->autodetect = true;
e246c333 626 state->powered = true;
bca7ad1a
FV
627 state->input = 0;
628 sd = &state->sd;
629 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
630
c9fbeddd
FV
631 ret = adv7180_init_controls(state);
632 if (ret)
bca7ad1a 633 goto err_unreg_subdev;
3999e5d0 634 ret = init_device(state);
c9fbeddd
FV
635 if (ret)
636 goto err_free_ctrl;
fa5b7945 637
fa5721d1
LPC
638 if (state->irq) {
639 ret = request_threaded_irq(client->irq, NULL, adv7180_irq,
f3e991d4
LPC
640 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
641 KBUILD_MODNAME, state);
fa5721d1
LPC
642 if (ret)
643 goto err_free_ctrl;
644 }
645
fa5b7945
LPC
646 ret = v4l2_async_register_subdev(sd);
647 if (ret)
648 goto err_free_irq;
649
6789cb52 650 return 0;
42752f7a 651
fa5b7945
LPC
652err_free_irq:
653 if (state->irq > 0)
654 free_irq(client->irq, state);
c9fbeddd
FV
655err_free_ctrl:
656 adv7180_exit_controls(state);
42752f7a 657err_unreg_subdev:
297a0ae3 658 mutex_destroy(&state->mutex);
42752f7a 659 return ret;
6789cb52
RR
660}
661
4c62e976 662static int adv7180_remove(struct i2c_client *client)
6789cb52
RR
663{
664 struct v4l2_subdev *sd = i2c_get_clientdata(client);
42752f7a
RR
665 struct adv7180_state *state = to_state(sd);
666
fa5b7945
LPC
667 v4l2_async_unregister_subdev(sd);
668
0c25534d 669 if (state->irq > 0)
42752f7a 670 free_irq(client->irq, state);
6789cb52 671
b13f4af2 672 adv7180_exit_controls(state);
297a0ae3 673 mutex_destroy(&state->mutex);
6789cb52
RR
674 return 0;
675}
676
677static const struct i2c_device_id adv7180_id[] = {
c9fbeddd 678 {KBUILD_MODNAME, 0},
6789cb52
RR
679 {},
680};
681
cc1088dc
LPC
682#ifdef CONFIG_PM_SLEEP
683static int adv7180_suspend(struct device *dev)
bca7ad1a 684{
cc1088dc 685 struct i2c_client *client = to_i2c_client(dev);
e246c333
LPC
686 struct v4l2_subdev *sd = i2c_get_clientdata(client);
687 struct adv7180_state *state = to_state(sd);
bca7ad1a 688
3999e5d0 689 return adv7180_set_power(state, false);
bca7ad1a
FV
690}
691
cc1088dc 692static int adv7180_resume(struct device *dev)
bca7ad1a 693{
cc1088dc 694 struct i2c_client *client = to_i2c_client(dev);
bca7ad1a
FV
695 struct v4l2_subdev *sd = i2c_get_clientdata(client);
696 struct adv7180_state *state = to_state(sd);
697 int ret;
698
3999e5d0 699 ret = init_device(state);
bca7ad1a
FV
700 if (ret < 0)
701 return ret;
c18818e9
LPC
702
703 ret = adv7180_set_power(state, state->powered);
704 if (ret)
705 return ret;
706
bca7ad1a
FV
707 return 0;
708}
cc1088dc
LPC
709
710static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
711#define ADV7180_PM_OPS (&adv7180_pm_ops)
712
713#else
714#define ADV7180_PM_OPS NULL
bca7ad1a
FV
715#endif
716
6789cb52
RR
717MODULE_DEVICE_TABLE(i2c, adv7180_id);
718
719static struct i2c_driver adv7180_driver = {
720 .driver = {
bca7ad1a 721 .owner = THIS_MODULE,
c9fbeddd 722 .name = KBUILD_MODNAME,
cc1088dc 723 .pm = ADV7180_PM_OPS,
bca7ad1a
FV
724 },
725 .probe = adv7180_probe,
4c62e976 726 .remove = adv7180_remove,
bca7ad1a 727 .id_table = adv7180_id,
6789cb52
RR
728};
729
c6e8d86f 730module_i2c_driver(adv7180_driver);
6789cb52
RR
731
732MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
733MODULE_AUTHOR("Mocean Laboratories");
734MODULE_LICENSE("GPL v2");
This page took 0.403153 seconds and 5 git commands to generate.