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