]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/i2c/adv7180.c
[media] adv7180: Add g_std operation
[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>
250121d3 28#include <linux/of.h>
6789cb52
RR
29#include <media/v4l2-ioctl.h>
30#include <linux/videodev2.h>
31#include <media/v4l2-device.h>
c9fbeddd 32#include <media/v4l2-ctrls.h>
42752f7a 33#include <linux/mutex.h>
c18818e9 34#include <linux/delay.h>
6789cb52 35
f5dde49b
LPC
36#define ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM 0x0
37#define ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM_PED 0x1
38#define ADV7180_STD_AD_PAL_N_NTSC_J_SECAM 0x2
39#define ADV7180_STD_AD_PAL_N_NTSC_M_SECAM 0x3
40#define ADV7180_STD_NTSC_J 0x4
41#define ADV7180_STD_NTSC_M 0x5
42#define ADV7180_STD_PAL60 0x6
43#define ADV7180_STD_NTSC_443 0x7
44#define ADV7180_STD_PAL_BG 0x8
45#define ADV7180_STD_PAL_N 0x9
46#define ADV7180_STD_PAL_M 0xa
47#define ADV7180_STD_PAL_M_PED 0xb
48#define ADV7180_STD_PAL_COMB_N 0xc
49#define ADV7180_STD_PAL_COMB_N_PED 0xd
50#define ADV7180_STD_PAL_SECAM 0xe
51#define ADV7180_STD_PAL_SECAM_PED 0xf
52
3999e5d0 53#define ADV7180_REG_INPUT_CONTROL 0x0000
bca7ad1a 54#define ADV7180_INPUT_CONTROL_INSEL_MASK 0x0f
d3124294 55
c5ef8f8c
LPC
56#define ADV7182_REG_INPUT_VIDSEL 0x0002
57
3999e5d0 58#define ADV7180_REG_EXTENDED_OUTPUT_CONTROL 0x0004
42752f7a 59#define ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS 0xC5
6789cb52 60
029d6177 61#define ADV7180_REG_AUTODETECT_ENABLE 0x07
42752f7a 62#define ADV7180_AUTODETECT_DEFAULT 0x7f
c9fbeddd 63/* Contrast */
3999e5d0 64#define ADV7180_REG_CON 0x0008 /*Unsigned */
c9fbeddd
FV
65#define ADV7180_CON_MIN 0
66#define ADV7180_CON_DEF 128
67#define ADV7180_CON_MAX 255
68/* Brightness*/
3999e5d0 69#define ADV7180_REG_BRI 0x000a /*Signed */
c9fbeddd
FV
70#define ADV7180_BRI_MIN -128
71#define ADV7180_BRI_DEF 0
72#define ADV7180_BRI_MAX 127
73/* Hue */
3999e5d0 74#define ADV7180_REG_HUE 0x000b /*Signed, inverted */
c9fbeddd
FV
75#define ADV7180_HUE_MIN -127
76#define ADV7180_HUE_DEF 0
77#define ADV7180_HUE_MAX 128
bca7ad1a 78
3999e5d0 79#define ADV7180_REG_CTRL 0x000e
029d6177 80#define ADV7180_CTRL_IRQ_SPACE 0x20
6789cb52 81
029d6177 82#define ADV7180_REG_PWR_MAN 0x0f
bca7ad1a
FV
83#define ADV7180_PWR_MAN_ON 0x04
84#define ADV7180_PWR_MAN_OFF 0x24
85#define ADV7180_PWR_MAN_RES 0x80
86
3999e5d0 87#define ADV7180_REG_STATUS1 0x0010
d3124294
RR
88#define ADV7180_STATUS1_IN_LOCK 0x01
89#define ADV7180_STATUS1_AUTOD_MASK 0x70
6789cb52
RR
90#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
91#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
92#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
93#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
94#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
95#define ADV7180_STATUS1_AUTOD_SECAM 0x50
96#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
97#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
98
3999e5d0 99#define ADV7180_REG_IDENT 0x0011
6789cb52
RR
100#define ADV7180_ID_7180 0x18
101
3999e5d0 102#define ADV7180_REG_ICONF1 0x0040
42752f7a
RR
103#define ADV7180_ICONF1_ACTIVE_LOW 0x01
104#define ADV7180_ICONF1_PSYNC_ONLY 0x10
105#define ADV7180_ICONF1_ACTIVE_TO_CLR 0xC0
c9fbeddd 106/* Saturation */
3999e5d0
LPC
107#define ADV7180_REG_SD_SAT_CB 0x00e3 /*Unsigned */
108#define ADV7180_REG_SD_SAT_CR 0x00e4 /*Unsigned */
c9fbeddd
FV
109#define ADV7180_SAT_MIN 0
110#define ADV7180_SAT_DEF 128
111#define ADV7180_SAT_MAX 255
bca7ad1a 112
42752f7a
RR
113#define ADV7180_IRQ1_LOCK 0x01
114#define ADV7180_IRQ1_UNLOCK 0x02
3999e5d0
LPC
115#define ADV7180_REG_ISR1 0x0042
116#define ADV7180_REG_ICR1 0x0043
117#define ADV7180_REG_IMR1 0x0044
118#define ADV7180_REG_IMR2 0x0048
42752f7a 119#define ADV7180_IRQ3_AD_CHANGE 0x08
3999e5d0
LPC
120#define ADV7180_REG_ISR3 0x004A
121#define ADV7180_REG_ICR3 0x004B
122#define ADV7180_REG_IMR3 0x004C
029d6177 123#define ADV7180_REG_IMR4 0x50
6789cb52 124
3999e5d0 125#define ADV7180_REG_NTSC_V_BIT_END 0x00E6
bca7ad1a
FV
126#define ADV7180_NTSC_V_BIT_END_MANUAL_NVEND 0x4F
127
851a54ef 128#define ADV7180_REG_VPP_SLAVE_ADDR 0xFD
b37135e3
LPC
129#define ADV7180_REG_CSI_SLAVE_ADDR 0xFE
130
08b717c2
LPC
131#define ADV7180_REG_FLCONTROL 0x40e0
132#define ADV7180_FLCONTROL_FL_ENABLE 0x1
133
b37135e3
LPC
134#define ADV7180_CSI_REG_PWRDN 0x00
135#define ADV7180_CSI_PWRDN 0x80
136
f5dde49b
LPC
137#define ADV7180_INPUT_CVBS_AIN1 0x00
138#define ADV7180_INPUT_CVBS_AIN2 0x01
139#define ADV7180_INPUT_CVBS_AIN3 0x02
140#define ADV7180_INPUT_CVBS_AIN4 0x03
141#define ADV7180_INPUT_CVBS_AIN5 0x04
142#define ADV7180_INPUT_CVBS_AIN6 0x05
143#define ADV7180_INPUT_SVIDEO_AIN1_AIN2 0x06
144#define ADV7180_INPUT_SVIDEO_AIN3_AIN4 0x07
145#define ADV7180_INPUT_SVIDEO_AIN5_AIN6 0x08
146#define ADV7180_INPUT_YPRPB_AIN1_AIN2_AIN3 0x09
147#define ADV7180_INPUT_YPRPB_AIN4_AIN5_AIN6 0x0a
148
c5ef8f8c
LPC
149#define ADV7182_INPUT_CVBS_AIN1 0x00
150#define ADV7182_INPUT_CVBS_AIN2 0x01
151#define ADV7182_INPUT_CVBS_AIN3 0x02
152#define ADV7182_INPUT_CVBS_AIN4 0x03
153#define ADV7182_INPUT_CVBS_AIN5 0x04
154#define ADV7182_INPUT_CVBS_AIN6 0x05
155#define ADV7182_INPUT_CVBS_AIN7 0x06
156#define ADV7182_INPUT_CVBS_AIN8 0x07
157#define ADV7182_INPUT_SVIDEO_AIN1_AIN2 0x08
158#define ADV7182_INPUT_SVIDEO_AIN3_AIN4 0x09
159#define ADV7182_INPUT_SVIDEO_AIN5_AIN6 0x0a
160#define ADV7182_INPUT_SVIDEO_AIN7_AIN8 0x0b
161#define ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3 0x0c
162#define ADV7182_INPUT_YPRPB_AIN4_AIN5_AIN6 0x0d
163#define ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2 0x0e
164#define ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4 0x0f
165#define ADV7182_INPUT_DIFF_CVBS_AIN5_AIN6 0x10
166#define ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8 0x11
167
b37135e3 168#define ADV7180_DEFAULT_CSI_I2C_ADDR 0x44
851a54ef 169#define ADV7180_DEFAULT_VPP_I2C_ADDR 0x42
b37135e3 170
08b717c2
LPC
171#define V4L2_CID_ADV_FAST_SWITCH (V4L2_CID_USER_ADV7180_BASE + 0x00)
172
f5dde49b
LPC
173struct adv7180_state;
174
175#define ADV7180_FLAG_RESET_POWERED BIT(0)
bf7dcb80 176#define ADV7180_FLAG_V2 BIT(1)
b37135e3 177#define ADV7180_FLAG_MIPI_CSI2 BIT(2)
851a54ef 178#define ADV7180_FLAG_I2P BIT(3)
f5dde49b
LPC
179
180struct adv7180_chip_info {
181 unsigned int flags;
182 unsigned int valid_input_mask;
183 int (*set_std)(struct adv7180_state *st, unsigned int std);
184 int (*select_input)(struct adv7180_state *st, unsigned int input);
185 int (*init)(struct adv7180_state *state);
186};
187
6789cb52 188struct adv7180_state {
c9fbeddd 189 struct v4l2_ctrl_handler ctrl_hdl;
c277b60a 190 struct v4l2_subdev sd;
d5d51a82 191 struct media_pad pad;
42752f7a
RR
192 struct mutex mutex; /* mutual excl. when accessing chip */
193 int irq;
c277b60a
RR
194 v4l2_std_id curr_norm;
195 bool autodetect;
e246c333 196 bool powered;
bca7ad1a 197 u8 input;
3999e5d0
LPC
198
199 struct i2c_client *client;
200 unsigned int register_page;
b37135e3 201 struct i2c_client *csi_client;
851a54ef 202 struct i2c_client *vpp_client;
f5dde49b 203 const struct adv7180_chip_info *chip_info;
851a54ef 204 enum v4l2_field field;
6789cb52 205};
c9fbeddd
FV
206#define to_adv7180_sd(_ctrl) (&container_of(_ctrl->handler, \
207 struct adv7180_state, \
208 ctrl_hdl)->sd)
6789cb52 209
3999e5d0
LPC
210static int adv7180_select_page(struct adv7180_state *state, unsigned int page)
211{
212 if (state->register_page != page) {
213 i2c_smbus_write_byte_data(state->client, ADV7180_REG_CTRL,
214 page);
215 state->register_page = page;
216 }
217
218 return 0;
219}
220
221static int adv7180_write(struct adv7180_state *state, unsigned int reg,
222 unsigned int value)
223{
224 lockdep_assert_held(&state->mutex);
225 adv7180_select_page(state, reg >> 8);
226 return i2c_smbus_write_byte_data(state->client, reg & 0xff, value);
227}
228
229static int adv7180_read(struct adv7180_state *state, unsigned int reg)
230{
231 lockdep_assert_held(&state->mutex);
232 adv7180_select_page(state, reg >> 8);
233 return i2c_smbus_read_byte_data(state->client, reg & 0xff);
234}
235
b37135e3
LPC
236static int adv7180_csi_write(struct adv7180_state *state, unsigned int reg,
237 unsigned int value)
238{
239 return i2c_smbus_write_byte_data(state->csi_client, reg, value);
240}
241
f5dde49b
LPC
242static int adv7180_set_video_standard(struct adv7180_state *state,
243 unsigned int std)
244{
245 return state->chip_info->set_std(state, std);
246}
3999e5d0 247
851a54ef
LPC
248static int adv7180_vpp_write(struct adv7180_state *state, unsigned int reg,
249 unsigned int value)
250{
251 return i2c_smbus_write_byte_data(state->vpp_client, reg, value);
252}
253
d3124294 254static v4l2_std_id adv7180_std_to_v4l2(u8 status1)
6789cb52 255{
b294a192
VB
256 /* in case V4L2_IN_ST_NO_SIGNAL */
257 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
258 return V4L2_STD_UNKNOWN;
259
6789cb52
RR
260 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
261 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
d3124294 262 return V4L2_STD_NTSC;
6789cb52
RR
263 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
264 return V4L2_STD_NTSC_443;
265 case ADV7180_STATUS1_AUTOD_PAL_M:
266 return V4L2_STD_PAL_M;
267 case ADV7180_STATUS1_AUTOD_PAL_60:
268 return V4L2_STD_PAL_60;
269 case ADV7180_STATUS1_AUTOD_PAL_B_G:
270 return V4L2_STD_PAL;
271 case ADV7180_STATUS1_AUTOD_SECAM:
272 return V4L2_STD_SECAM;
273 case ADV7180_STATUS1_AUTOD_PAL_COMB:
274 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
275 case ADV7180_STATUS1_AUTOD_SECAM_525:
276 return V4L2_STD_SECAM;
277 default:
278 return V4L2_STD_UNKNOWN;
279 }
280}
281
c277b60a
RR
282static int v4l2_std_to_adv7180(v4l2_std_id std)
283{
284 if (std == V4L2_STD_PAL_60)
f5dde49b 285 return ADV7180_STD_PAL60;
c277b60a 286 if (std == V4L2_STD_NTSC_443)
f5dde49b 287 return ADV7180_STD_NTSC_443;
c277b60a 288 if (std == V4L2_STD_PAL_N)
f5dde49b 289 return ADV7180_STD_PAL_N;
c277b60a 290 if (std == V4L2_STD_PAL_M)
f5dde49b 291 return ADV7180_STD_PAL_M;
c277b60a 292 if (std == V4L2_STD_PAL_Nc)
f5dde49b 293 return ADV7180_STD_PAL_COMB_N;
c277b60a
RR
294
295 if (std & V4L2_STD_PAL)
f5dde49b 296 return ADV7180_STD_PAL_BG;
c277b60a 297 if (std & V4L2_STD_NTSC)
f5dde49b 298 return ADV7180_STD_NTSC_M;
c277b60a 299 if (std & V4L2_STD_SECAM)
f5dde49b 300 return ADV7180_STD_PAL_SECAM;
c277b60a
RR
301
302 return -EINVAL;
303}
304
d3124294
RR
305static u32 adv7180_status_to_v4l2(u8 status1)
306{
307 if (!(status1 & ADV7180_STATUS1_IN_LOCK))
308 return V4L2_IN_ST_NO_SIGNAL;
309
310 return 0;
311}
312
3999e5d0 313static int __adv7180_status(struct adv7180_state *state, u32 *status,
bca7ad1a 314 v4l2_std_id *std)
d3124294 315{
3999e5d0 316 int status1 = adv7180_read(state, ADV7180_REG_STATUS1);
d3124294
RR
317
318 if (status1 < 0)
319 return status1;
320
321 if (status)
322 *status = adv7180_status_to_v4l2(status1);
323 if (std)
324 *std = adv7180_std_to_v4l2(status1);
325
326 return 0;
327}
328
6789cb52
RR
329static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
330{
331 return container_of(sd, struct adv7180_state, sd);
332}
333
334static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
335{
c277b60a 336 struct adv7180_state *state = to_state(sd);
42752f7a
RR
337 int err = mutex_lock_interruptible(&state->mutex);
338 if (err)
339 return err;
c277b60a 340
42752f7a
RR
341 /* when we are interrupt driven we know the state */
342 if (!state->autodetect || state->irq > 0)
c277b60a
RR
343 *std = state->curr_norm;
344 else
3999e5d0 345 err = __adv7180_status(state, NULL, std);
c277b60a 346
42752f7a 347 mutex_unlock(&state->mutex);
c277b60a 348 return err;
d3124294 349}
6789cb52 350
bca7ad1a
FV
351static int adv7180_s_routing(struct v4l2_subdev *sd, u32 input,
352 u32 output, u32 config)
353{
354 struct adv7180_state *state = to_state(sd);
355 int ret = mutex_lock_interruptible(&state->mutex);
bca7ad1a
FV
356
357 if (ret)
358 return ret;
359
f5dde49b
LPC
360 if (input > 31 || !(BIT(input) & state->chip_info->valid_input_mask)) {
361 ret = -EINVAL;
bca7ad1a 362 goto out;
f5dde49b 363 }
bca7ad1a 364
f5dde49b 365 ret = state->chip_info->select_input(state, input);
bca7ad1a 366
f5dde49b
LPC
367 if (ret == 0)
368 state->input = input;
bca7ad1a
FV
369out:
370 mutex_unlock(&state->mutex);
371 return ret;
372}
373
d3124294
RR
374static int adv7180_g_input_status(struct v4l2_subdev *sd, u32 *status)
375{
42752f7a
RR
376 struct adv7180_state *state = to_state(sd);
377 int ret = mutex_lock_interruptible(&state->mutex);
378 if (ret)
379 return ret;
380
3999e5d0 381 ret = __adv7180_status(state, status, NULL);
42752f7a
RR
382 mutex_unlock(&state->mutex);
383 return ret;
6789cb52
RR
384}
385
3e35e33c 386static int adv7180_program_std(struct adv7180_state *state)
c277b60a 387{
3e35e33c 388 int ret;
c277b60a 389
3e35e33c 390 if (state->autodetect) {
f5dde49b
LPC
391 ret = adv7180_set_video_standard(state,
392 ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM);
c277b60a 393 if (ret < 0)
3e35e33c 394 return ret;
c277b60a 395
3999e5d0 396 __adv7180_status(state, NULL, &state->curr_norm);
c277b60a 397 } else {
3e35e33c 398 ret = v4l2_std_to_adv7180(state->curr_norm);
c277b60a 399 if (ret < 0)
3e35e33c 400 return ret;
c277b60a 401
f5dde49b 402 ret = adv7180_set_video_standard(state, ret);
3e35e33c
LPC
403 if (ret < 0)
404 return ret;
405 }
406
407 return 0;
408}
409
410static int adv7180_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
411{
412 struct adv7180_state *state = to_state(sd);
413 int ret = mutex_lock_interruptible(&state->mutex);
414
415 if (ret)
416 return ret;
417
418 /* all standards -> autodetect */
419 if (std == V4L2_STD_ALL) {
420 state->autodetect = true;
421 } else {
422 /* Make sure we can support this std */
423 ret = v4l2_std_to_adv7180(std);
c277b60a
RR
424 if (ret < 0)
425 goto out;
426
427 state->curr_norm = std;
428 state->autodetect = false;
429 }
3e35e33c
LPC
430
431 ret = adv7180_program_std(state);
c277b60a 432out:
42752f7a 433 mutex_unlock(&state->mutex);
c277b60a
RR
434 return ret;
435}
436
d0fadc86
NS
437static int adv7180_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
438{
439 struct adv7180_state *state = to_state(sd);
440
441 *norm = state->curr_norm;
442
443 return 0;
444}
445
3999e5d0 446static int adv7180_set_power(struct adv7180_state *state, bool on)
e246c333
LPC
447{
448 u8 val;
b37135e3 449 int ret;
e246c333
LPC
450
451 if (on)
452 val = ADV7180_PWR_MAN_ON;
453 else
454 val = ADV7180_PWR_MAN_OFF;
455
b37135e3
LPC
456 ret = adv7180_write(state, ADV7180_REG_PWR_MAN, val);
457 if (ret)
458 return ret;
459
460 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
461 if (on) {
462 adv7180_csi_write(state, 0xDE, 0x02);
463 adv7180_csi_write(state, 0xD2, 0xF7);
464 adv7180_csi_write(state, 0xD8, 0x65);
465 adv7180_csi_write(state, 0xE0, 0x09);
466 adv7180_csi_write(state, 0x2C, 0x00);
851a54ef
LPC
467 if (state->field == V4L2_FIELD_NONE)
468 adv7180_csi_write(state, 0x1D, 0x80);
b37135e3
LPC
469 adv7180_csi_write(state, 0x00, 0x00);
470 } else {
471 adv7180_csi_write(state, 0x00, 0x80);
472 }
473 }
474
475 return 0;
e246c333
LPC
476}
477
478static int adv7180_s_power(struct v4l2_subdev *sd, int on)
479{
480 struct adv7180_state *state = to_state(sd);
e246c333
LPC
481 int ret;
482
483 ret = mutex_lock_interruptible(&state->mutex);
484 if (ret)
485 return ret;
486
3999e5d0 487 ret = adv7180_set_power(state, on);
e246c333
LPC
488 if (ret == 0)
489 state->powered = on;
490
491 mutex_unlock(&state->mutex);
492 return ret;
493}
494
c9fbeddd 495static int adv7180_s_ctrl(struct v4l2_ctrl *ctrl)
bca7ad1a 496{
c9fbeddd 497 struct v4l2_subdev *sd = to_adv7180_sd(ctrl);
bca7ad1a 498 struct adv7180_state *state = to_state(sd);
bca7ad1a 499 int ret = mutex_lock_interruptible(&state->mutex);
c9fbeddd
FV
500 int val;
501
bca7ad1a
FV
502 if (ret)
503 return ret;
c9fbeddd 504 val = ctrl->val;
bca7ad1a
FV
505 switch (ctrl->id) {
506 case V4L2_CID_BRIGHTNESS:
3999e5d0 507 ret = adv7180_write(state, ADV7180_REG_BRI, val);
bca7ad1a
FV
508 break;
509 case V4L2_CID_HUE:
bca7ad1a 510 /*Hue is inverted according to HSL chart */
3999e5d0 511 ret = adv7180_write(state, ADV7180_REG_HUE, -val);
bca7ad1a
FV
512 break;
513 case V4L2_CID_CONTRAST:
3999e5d0 514 ret = adv7180_write(state, ADV7180_REG_CON, val);
bca7ad1a
FV
515 break;
516 case V4L2_CID_SATURATION:
bca7ad1a
FV
517 /*
518 *This could be V4L2_CID_BLUE_BALANCE/V4L2_CID_RED_BALANCE
519 *Let's not confuse the user, everybody understands saturation
520 */
3999e5d0 521 ret = adv7180_write(state, ADV7180_REG_SD_SAT_CB, val);
bca7ad1a
FV
522 if (ret < 0)
523 break;
3999e5d0 524 ret = adv7180_write(state, ADV7180_REG_SD_SAT_CR, val);
bca7ad1a 525 break;
08b717c2
LPC
526 case V4L2_CID_ADV_FAST_SWITCH:
527 if (ctrl->val) {
528 /* ADI required write */
529 adv7180_write(state, 0x80d9, 0x44);
530 adv7180_write(state, ADV7180_REG_FLCONTROL,
531 ADV7180_FLCONTROL_FL_ENABLE);
532 } else {
533 /* ADI required write */
534 adv7180_write(state, 0x80d9, 0xc4);
535 adv7180_write(state, ADV7180_REG_FLCONTROL, 0x00);
536 }
537 break;
bca7ad1a
FV
538 default:
539 ret = -EINVAL;
540 }
541
542 mutex_unlock(&state->mutex);
543 return ret;
544}
545
c9fbeddd
FV
546static const struct v4l2_ctrl_ops adv7180_ctrl_ops = {
547 .s_ctrl = adv7180_s_ctrl,
548};
549
08b717c2
LPC
550static const struct v4l2_ctrl_config adv7180_ctrl_fast_switch = {
551 .ops = &adv7180_ctrl_ops,
552 .id = V4L2_CID_ADV_FAST_SWITCH,
553 .name = "Fast Switching",
554 .type = V4L2_CTRL_TYPE_BOOLEAN,
555 .min = 0,
556 .max = 1,
557 .step = 1,
558};
559
c9fbeddd
FV
560static int adv7180_init_controls(struct adv7180_state *state)
561{
562 v4l2_ctrl_handler_init(&state->ctrl_hdl, 4);
563
564 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
565 V4L2_CID_BRIGHTNESS, ADV7180_BRI_MIN,
566 ADV7180_BRI_MAX, 1, ADV7180_BRI_DEF);
567 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
568 V4L2_CID_CONTRAST, ADV7180_CON_MIN,
569 ADV7180_CON_MAX, 1, ADV7180_CON_DEF);
570 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
571 V4L2_CID_SATURATION, ADV7180_SAT_MIN,
572 ADV7180_SAT_MAX, 1, ADV7180_SAT_DEF);
573 v4l2_ctrl_new_std(&state->ctrl_hdl, &adv7180_ctrl_ops,
574 V4L2_CID_HUE, ADV7180_HUE_MIN,
575 ADV7180_HUE_MAX, 1, ADV7180_HUE_DEF);
08b717c2
LPC
576 v4l2_ctrl_new_custom(&state->ctrl_hdl, &adv7180_ctrl_fast_switch, NULL);
577
c9fbeddd
FV
578 state->sd.ctrl_handler = &state->ctrl_hdl;
579 if (state->ctrl_hdl.error) {
580 int err = state->ctrl_hdl.error;
581
582 v4l2_ctrl_handler_free(&state->ctrl_hdl);
583 return err;
584 }
585 v4l2_ctrl_handler_setup(&state->ctrl_hdl);
586
587 return 0;
588}
589static void adv7180_exit_controls(struct adv7180_state *state)
590{
591 v4l2_ctrl_handler_free(&state->ctrl_hdl);
592}
593
d5d51a82 594static int adv7180_enum_mbus_code(struct v4l2_subdev *sd,
f7234138 595 struct v4l2_subdev_pad_config *cfg,
d5d51a82 596 struct v4l2_subdev_mbus_code_enum *code)
cccb83f7 597{
d5d51a82 598 if (code->index != 0)
cccb83f7
VB
599 return -EINVAL;
600
d5d51a82 601 code->code = MEDIA_BUS_FMT_YUYV8_2X8;
cccb83f7
VB
602
603 return 0;
604}
605
606static int adv7180_mbus_fmt(struct v4l2_subdev *sd,
607 struct v4l2_mbus_framefmt *fmt)
608{
609 struct adv7180_state *state = to_state(sd);
610
f5fe58fd 611 fmt->code = MEDIA_BUS_FMT_YUYV8_2X8;
cccb83f7 612 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
cccb83f7
VB
613 fmt->width = 720;
614 fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
615
616 return 0;
617}
618
851a54ef
LPC
619static int adv7180_set_field_mode(struct adv7180_state *state)
620{
621 if (!(state->chip_info->flags & ADV7180_FLAG_I2P))
622 return 0;
623
624 if (state->field == V4L2_FIELD_NONE) {
625 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
626 adv7180_csi_write(state, 0x01, 0x20);
627 adv7180_csi_write(state, 0x02, 0x28);
628 adv7180_csi_write(state, 0x03, 0x38);
629 adv7180_csi_write(state, 0x04, 0x30);
630 adv7180_csi_write(state, 0x05, 0x30);
631 adv7180_csi_write(state, 0x06, 0x80);
632 adv7180_csi_write(state, 0x07, 0x70);
633 adv7180_csi_write(state, 0x08, 0x50);
634 }
635 adv7180_vpp_write(state, 0xa3, 0x00);
636 adv7180_vpp_write(state, 0x5b, 0x00);
637 adv7180_vpp_write(state, 0x55, 0x80);
638 } else {
639 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
640 adv7180_csi_write(state, 0x01, 0x18);
641 adv7180_csi_write(state, 0x02, 0x18);
642 adv7180_csi_write(state, 0x03, 0x30);
643 adv7180_csi_write(state, 0x04, 0x20);
644 adv7180_csi_write(state, 0x05, 0x28);
645 adv7180_csi_write(state, 0x06, 0x40);
646 adv7180_csi_write(state, 0x07, 0x58);
647 adv7180_csi_write(state, 0x08, 0x30);
648 }
649 adv7180_vpp_write(state, 0xa3, 0x70);
650 adv7180_vpp_write(state, 0x5b, 0x80);
651 adv7180_vpp_write(state, 0x55, 0x00);
652 }
653
654 return 0;
655}
656
d5d51a82 657static int adv7180_get_pad_format(struct v4l2_subdev *sd,
f7234138 658 struct v4l2_subdev_pad_config *cfg,
d5d51a82
LPC
659 struct v4l2_subdev_format *format)
660{
851a54ef
LPC
661 struct adv7180_state *state = to_state(sd);
662
663 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
f7234138 664 format->format = *v4l2_subdev_get_try_format(sd, cfg, 0);
851a54ef
LPC
665 } else {
666 adv7180_mbus_fmt(sd, &format->format);
667 format->format.field = state->field;
668 }
669
670 return 0;
d5d51a82
LPC
671}
672
673static int adv7180_set_pad_format(struct v4l2_subdev *sd,
f7234138 674 struct v4l2_subdev_pad_config *cfg,
d5d51a82
LPC
675 struct v4l2_subdev_format *format)
676{
851a54ef
LPC
677 struct adv7180_state *state = to_state(sd);
678 struct v4l2_mbus_framefmt *framefmt;
679
680 switch (format->format.field) {
681 case V4L2_FIELD_NONE:
682 if (!(state->chip_info->flags & ADV7180_FLAG_I2P))
683 format->format.field = V4L2_FIELD_INTERLACED;
684 break;
685 default:
686 format->format.field = V4L2_FIELD_INTERLACED;
687 break;
688 }
689
690 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
691 framefmt = &format->format;
692 if (state->field != format->format.field) {
693 state->field = format->format.field;
694 adv7180_set_power(state, false);
695 adv7180_set_field_mode(state);
696 adv7180_set_power(state, true);
697 }
698 } else {
f7234138 699 framefmt = v4l2_subdev_get_try_format(sd, cfg, 0);
851a54ef
LPC
700 *framefmt = format->format;
701 }
702
703 return adv7180_mbus_fmt(sd, framefmt);
d5d51a82
LPC
704}
705
cccb83f7
VB
706static int adv7180_g_mbus_config(struct v4l2_subdev *sd,
707 struct v4l2_mbus_config *cfg)
708{
b37135e3
LPC
709 struct adv7180_state *state = to_state(sd);
710
711 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
712 cfg->type = V4L2_MBUS_CSI2;
713 cfg->flags = V4L2_MBUS_CSI2_1_LANE |
714 V4L2_MBUS_CSI2_CHANNEL_0 |
715 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
716 } else {
717 /*
718 * The ADV7180 sensor supports BT.601/656 output modes.
719 * The BT.656 is default and not yet configurable by s/w.
720 */
721 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
722 V4L2_MBUS_DATA_ACTIVE_HIGH;
723 cfg->type = V4L2_MBUS_BT656;
724 }
cccb83f7
VB
725
726 return 0;
727}
728
6789cb52 729static const struct v4l2_subdev_video_ops adv7180_video_ops = {
8774bed9 730 .s_std = adv7180_s_std,
d0fadc86 731 .g_std = adv7180_g_std,
6789cb52 732 .querystd = adv7180_querystd,
d3124294 733 .g_input_status = adv7180_g_input_status,
bca7ad1a 734 .s_routing = adv7180_s_routing,
cccb83f7 735 .g_mbus_config = adv7180_g_mbus_config,
6789cb52
RR
736};
737
f5dde49b 738
6789cb52 739static const struct v4l2_subdev_core_ops adv7180_core_ops = {
e246c333 740 .s_power = adv7180_s_power,
6789cb52
RR
741};
742
d5d51a82
LPC
743static const struct v4l2_subdev_pad_ops adv7180_pad_ops = {
744 .enum_mbus_code = adv7180_enum_mbus_code,
745 .set_fmt = adv7180_set_pad_format,
746 .get_fmt = adv7180_get_pad_format,
747};
748
6789cb52
RR
749static const struct v4l2_subdev_ops adv7180_ops = {
750 .core = &adv7180_core_ops,
751 .video = &adv7180_video_ops,
d5d51a82 752 .pad = &adv7180_pad_ops,
6789cb52
RR
753};
754
0c25534d 755static irqreturn_t adv7180_irq(int irq, void *devid)
42752f7a 756{
0c25534d 757 struct adv7180_state *state = devid;
42752f7a
RR
758 u8 isr3;
759
760 mutex_lock(&state->mutex);
3999e5d0 761 isr3 = adv7180_read(state, ADV7180_REG_ISR3);
42752f7a 762 /* clear */
3999e5d0 763 adv7180_write(state, ADV7180_REG_ICR3, isr3);
42752f7a
RR
764
765 if (isr3 & ADV7180_IRQ3_AD_CHANGE && state->autodetect)
3999e5d0 766 __adv7180_status(state, NULL, &state->curr_norm);
42752f7a
RR
767 mutex_unlock(&state->mutex);
768
42752f7a
RR
769 return IRQ_HANDLED;
770}
771
f5dde49b 772static int adv7180_init(struct adv7180_state *state)
6789cb52 773{
6789cb52
RR
774 int ret;
775
42752f7a 776 /* ITU-R BT.656-4 compatible */
3999e5d0 777 ret = adv7180_write(state, ADV7180_REG_EXTENDED_OUTPUT_CONTROL,
bca7ad1a 778 ADV7180_EXTENDED_OUTPUT_CONTROL_NTSCDIS);
42752f7a 779 if (ret < 0)
f5dde49b 780 return ret;
bca7ad1a
FV
781
782 /* Manually set V bit end position in NTSC mode */
f5dde49b 783 return adv7180_write(state, ADV7180_REG_NTSC_V_BIT_END,
bca7ad1a 784 ADV7180_NTSC_V_BIT_END_MANUAL_NVEND);
f5dde49b
LPC
785}
786
787static int adv7180_set_std(struct adv7180_state *state, unsigned int std)
788{
789 return adv7180_write(state, ADV7180_REG_INPUT_CONTROL,
790 (std << 4) | state->input);
791}
792
793static int adv7180_select_input(struct adv7180_state *state, unsigned int input)
794{
795 int ret;
796
797 ret = adv7180_read(state, ADV7180_REG_INPUT_CONTROL);
bca7ad1a 798 if (ret < 0)
f5dde49b
LPC
799 return ret;
800
801 ret &= ~ADV7180_INPUT_CONTROL_INSEL_MASK;
802 ret |= input;
803 return adv7180_write(state, ADV7180_REG_INPUT_CONTROL, ret);
804}
805
c5ef8f8c
LPC
806static int adv7182_init(struct adv7180_state *state)
807{
b37135e3
LPC
808 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
809 adv7180_write(state, ADV7180_REG_CSI_SLAVE_ADDR,
810 ADV7180_DEFAULT_CSI_I2C_ADDR << 1);
811
851a54ef
LPC
812 if (state->chip_info->flags & ADV7180_FLAG_I2P)
813 adv7180_write(state, ADV7180_REG_VPP_SLAVE_ADDR,
814 ADV7180_DEFAULT_VPP_I2C_ADDR << 1);
815
bf7dcb80
LPC
816 if (state->chip_info->flags & ADV7180_FLAG_V2) {
817 /* ADI recommended writes for improved video quality */
818 adv7180_write(state, 0x0080, 0x51);
819 adv7180_write(state, 0x0081, 0x51);
820 adv7180_write(state, 0x0082, 0x68);
bf7dcb80
LPC
821 }
822
c5ef8f8c 823 /* ADI required writes */
b37135e3
LPC
824 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
825 adv7180_write(state, 0x0003, 0x4e);
826 adv7180_write(state, 0x0004, 0x57);
827 adv7180_write(state, 0x001d, 0xc0);
828 } else {
829 if (state->chip_info->flags & ADV7180_FLAG_V2)
830 adv7180_write(state, 0x0004, 0x17);
831 else
832 adv7180_write(state, 0x0004, 0x07);
833 adv7180_write(state, 0x0003, 0x0c);
834 adv7180_write(state, 0x001d, 0x40);
835 }
836
c5ef8f8c 837 adv7180_write(state, 0x0013, 0x00);
c5ef8f8c
LPC
838
839 return 0;
840}
841
842static int adv7182_set_std(struct adv7180_state *state, unsigned int std)
843{
844 return adv7180_write(state, ADV7182_REG_INPUT_VIDSEL, std << 4);
845}
846
847enum adv7182_input_type {
848 ADV7182_INPUT_TYPE_CVBS,
849 ADV7182_INPUT_TYPE_DIFF_CVBS,
850 ADV7182_INPUT_TYPE_SVIDEO,
851 ADV7182_INPUT_TYPE_YPBPR,
852};
853
854static enum adv7182_input_type adv7182_get_input_type(unsigned int input)
855{
856 switch (input) {
857 case ADV7182_INPUT_CVBS_AIN1:
858 case ADV7182_INPUT_CVBS_AIN2:
859 case ADV7182_INPUT_CVBS_AIN3:
860 case ADV7182_INPUT_CVBS_AIN4:
861 case ADV7182_INPUT_CVBS_AIN5:
862 case ADV7182_INPUT_CVBS_AIN6:
863 case ADV7182_INPUT_CVBS_AIN7:
864 case ADV7182_INPUT_CVBS_AIN8:
865 return ADV7182_INPUT_TYPE_CVBS;
866 case ADV7182_INPUT_SVIDEO_AIN1_AIN2:
867 case ADV7182_INPUT_SVIDEO_AIN3_AIN4:
868 case ADV7182_INPUT_SVIDEO_AIN5_AIN6:
869 case ADV7182_INPUT_SVIDEO_AIN7_AIN8:
870 return ADV7182_INPUT_TYPE_SVIDEO;
871 case ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3:
872 case ADV7182_INPUT_YPRPB_AIN4_AIN5_AIN6:
873 return ADV7182_INPUT_TYPE_YPBPR;
874 case ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2:
875 case ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4:
876 case ADV7182_INPUT_DIFF_CVBS_AIN5_AIN6:
877 case ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8:
878 return ADV7182_INPUT_TYPE_DIFF_CVBS;
879 default: /* Will never happen */
880 return 0;
881 }
882}
883
884/* ADI recommended writes to registers 0x52, 0x53, 0x54 */
885static unsigned int adv7182_lbias_settings[][3] = {
886 [ADV7182_INPUT_TYPE_CVBS] = { 0xCB, 0x4E, 0x80 },
887 [ADV7182_INPUT_TYPE_DIFF_CVBS] = { 0xC0, 0x4E, 0x80 },
888 [ADV7182_INPUT_TYPE_SVIDEO] = { 0x0B, 0xCE, 0x80 },
889 [ADV7182_INPUT_TYPE_YPBPR] = { 0x0B, 0x4E, 0xC0 },
890};
891
bf7dcb80
LPC
892static unsigned int adv7280_lbias_settings[][3] = {
893 [ADV7182_INPUT_TYPE_CVBS] = { 0xCD, 0x4E, 0x80 },
894 [ADV7182_INPUT_TYPE_DIFF_CVBS] = { 0xC0, 0x4E, 0x80 },
895 [ADV7182_INPUT_TYPE_SVIDEO] = { 0x0B, 0xCE, 0x80 },
896 [ADV7182_INPUT_TYPE_YPBPR] = { 0x0B, 0x4E, 0xC0 },
897};
898
c5ef8f8c
LPC
899static int adv7182_select_input(struct adv7180_state *state, unsigned int input)
900{
901 enum adv7182_input_type input_type;
902 unsigned int *lbias;
903 unsigned int i;
904 int ret;
905
906 ret = adv7180_write(state, ADV7180_REG_INPUT_CONTROL, input);
907 if (ret)
908 return ret;
909
910 /* Reset clamp circuitry - ADI recommended writes */
911 adv7180_write(state, 0x809c, 0x00);
912 adv7180_write(state, 0x809c, 0xff);
913
914 input_type = adv7182_get_input_type(input);
915
916 switch (input_type) {
917 case ADV7182_INPUT_TYPE_CVBS:
918 case ADV7182_INPUT_TYPE_DIFF_CVBS:
919 /* ADI recommends to use the SH1 filter */
920 adv7180_write(state, 0x0017, 0x41);
921 break;
922 default:
923 adv7180_write(state, 0x0017, 0x01);
924 break;
925 }
926
bf7dcb80
LPC
927 if (state->chip_info->flags & ADV7180_FLAG_V2)
928 lbias = adv7280_lbias_settings[input_type];
929 else
930 lbias = adv7182_lbias_settings[input_type];
c5ef8f8c
LPC
931
932 for (i = 0; i < ARRAY_SIZE(adv7182_lbias_settings[0]); i++)
933 adv7180_write(state, 0x0052 + i, lbias[i]);
934
935 if (input_type == ADV7182_INPUT_TYPE_DIFF_CVBS) {
936 /* ADI required writes to make differential CVBS work */
937 adv7180_write(state, 0x005f, 0xa8);
938 adv7180_write(state, 0x005a, 0x90);
939 adv7180_write(state, 0x0060, 0xb0);
940 adv7180_write(state, 0x80b6, 0x08);
941 adv7180_write(state, 0x80c0, 0xa0);
942 } else {
943 adv7180_write(state, 0x005f, 0xf0);
944 adv7180_write(state, 0x005a, 0xd0);
945 adv7180_write(state, 0x0060, 0x10);
946 adv7180_write(state, 0x80b6, 0x9c);
947 adv7180_write(state, 0x80c0, 0x00);
948 }
949
950 return 0;
951}
952
f5dde49b
LPC
953static const struct adv7180_chip_info adv7180_info = {
954 .flags = ADV7180_FLAG_RESET_POWERED,
955 /* We cannot discriminate between LQFP and 40-pin LFCSP, so accept
956 * all inputs and let the card driver take care of validation
957 */
958 .valid_input_mask = BIT(ADV7180_INPUT_CVBS_AIN1) |
959 BIT(ADV7180_INPUT_CVBS_AIN2) |
960 BIT(ADV7180_INPUT_CVBS_AIN3) |
961 BIT(ADV7180_INPUT_CVBS_AIN4) |
962 BIT(ADV7180_INPUT_CVBS_AIN5) |
963 BIT(ADV7180_INPUT_CVBS_AIN6) |
964 BIT(ADV7180_INPUT_SVIDEO_AIN1_AIN2) |
965 BIT(ADV7180_INPUT_SVIDEO_AIN3_AIN4) |
966 BIT(ADV7180_INPUT_SVIDEO_AIN5_AIN6) |
967 BIT(ADV7180_INPUT_YPRPB_AIN1_AIN2_AIN3) |
968 BIT(ADV7180_INPUT_YPRPB_AIN4_AIN5_AIN6),
969 .init = adv7180_init,
970 .set_std = adv7180_set_std,
971 .select_input = adv7180_select_input,
972};
973
c5ef8f8c
LPC
974static const struct adv7180_chip_info adv7182_info = {
975 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
976 BIT(ADV7182_INPUT_CVBS_AIN2) |
977 BIT(ADV7182_INPUT_CVBS_AIN3) |
978 BIT(ADV7182_INPUT_CVBS_AIN4) |
979 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
980 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
981 BIT(ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3) |
982 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
983 BIT(ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4),
984 .init = adv7182_init,
985 .set_std = adv7182_set_std,
986 .select_input = adv7182_select_input,
987};
988
bf7dcb80 989static const struct adv7180_chip_info adv7280_info = {
851a54ef 990 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P,
bf7dcb80
LPC
991 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
992 BIT(ADV7182_INPUT_CVBS_AIN2) |
993 BIT(ADV7182_INPUT_CVBS_AIN3) |
994 BIT(ADV7182_INPUT_CVBS_AIN4) |
995 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
996 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
997 BIT(ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3),
998 .init = adv7182_init,
999 .set_std = adv7182_set_std,
1000 .select_input = adv7182_select_input,
1001};
1002
b37135e3 1003static const struct adv7180_chip_info adv7280_m_info = {
851a54ef 1004 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P,
b37135e3
LPC
1005 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1006 BIT(ADV7182_INPUT_CVBS_AIN2) |
1007 BIT(ADV7182_INPUT_CVBS_AIN3) |
1008 BIT(ADV7182_INPUT_CVBS_AIN4) |
1009 BIT(ADV7182_INPUT_CVBS_AIN5) |
1010 BIT(ADV7182_INPUT_CVBS_AIN6) |
1011 BIT(ADV7182_INPUT_CVBS_AIN7) |
1012 BIT(ADV7182_INPUT_CVBS_AIN8) |
1013 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
1014 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
1015 BIT(ADV7182_INPUT_SVIDEO_AIN5_AIN6) |
1016 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
1017 BIT(ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3) |
1018 BIT(ADV7182_INPUT_YPRPB_AIN4_AIN5_AIN6),
1019 .init = adv7182_init,
1020 .set_std = adv7182_set_std,
1021 .select_input = adv7182_select_input,
1022};
1023
bf7dcb80 1024static const struct adv7180_chip_info adv7281_info = {
b37135e3
LPC
1025 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2,
1026 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1027 BIT(ADV7182_INPUT_CVBS_AIN2) |
1028 BIT(ADV7182_INPUT_CVBS_AIN7) |
1029 BIT(ADV7182_INPUT_CVBS_AIN8) |
1030 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
1031 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
1032 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
1033 BIT(ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8),
1034 .init = adv7182_init,
1035 .set_std = adv7182_set_std,
1036 .select_input = adv7182_select_input,
1037};
1038
1039static const struct adv7180_chip_info adv7281_m_info = {
1040 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2,
1041 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1042 BIT(ADV7182_INPUT_CVBS_AIN2) |
1043 BIT(ADV7182_INPUT_CVBS_AIN3) |
1044 BIT(ADV7182_INPUT_CVBS_AIN4) |
1045 BIT(ADV7182_INPUT_CVBS_AIN7) |
1046 BIT(ADV7182_INPUT_CVBS_AIN8) |
1047 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
1048 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
1049 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
1050 BIT(ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3) |
1051 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
1052 BIT(ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4) |
1053 BIT(ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8),
1054 .init = adv7182_init,
1055 .set_std = adv7182_set_std,
1056 .select_input = adv7182_select_input,
1057};
1058
1059static const struct adv7180_chip_info adv7281_ma_info = {
1060 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2,
bf7dcb80
LPC
1061 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1062 BIT(ADV7182_INPUT_CVBS_AIN2) |
b37135e3
LPC
1063 BIT(ADV7182_INPUT_CVBS_AIN3) |
1064 BIT(ADV7182_INPUT_CVBS_AIN4) |
1065 BIT(ADV7182_INPUT_CVBS_AIN5) |
1066 BIT(ADV7182_INPUT_CVBS_AIN6) |
bf7dcb80
LPC
1067 BIT(ADV7182_INPUT_CVBS_AIN7) |
1068 BIT(ADV7182_INPUT_CVBS_AIN8) |
1069 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
b37135e3
LPC
1070 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
1071 BIT(ADV7182_INPUT_SVIDEO_AIN5_AIN6) |
bf7dcb80 1072 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
b37135e3
LPC
1073 BIT(ADV7182_INPUT_YPRPB_AIN1_AIN2_AIN3) |
1074 BIT(ADV7182_INPUT_YPRPB_AIN4_AIN5_AIN6) |
bf7dcb80 1075 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
b37135e3
LPC
1076 BIT(ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4) |
1077 BIT(ADV7182_INPUT_DIFF_CVBS_AIN5_AIN6) |
bf7dcb80
LPC
1078 BIT(ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8),
1079 .init = adv7182_init,
1080 .set_std = adv7182_set_std,
1081 .select_input = adv7182_select_input,
1082};
1083
851a54ef
LPC
1084static const struct adv7180_chip_info adv7282_info = {
1085 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_I2P,
1086 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1087 BIT(ADV7182_INPUT_CVBS_AIN2) |
1088 BIT(ADV7182_INPUT_CVBS_AIN7) |
1089 BIT(ADV7182_INPUT_CVBS_AIN8) |
1090 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
1091 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
1092 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
1093 BIT(ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8),
1094 .init = adv7182_init,
1095 .set_std = adv7182_set_std,
1096 .select_input = adv7182_select_input,
1097};
1098
1099static const struct adv7180_chip_info adv7282_m_info = {
1100 .flags = ADV7180_FLAG_V2 | ADV7180_FLAG_MIPI_CSI2 | ADV7180_FLAG_I2P,
1101 .valid_input_mask = BIT(ADV7182_INPUT_CVBS_AIN1) |
1102 BIT(ADV7182_INPUT_CVBS_AIN2) |
1103 BIT(ADV7182_INPUT_CVBS_AIN3) |
1104 BIT(ADV7182_INPUT_CVBS_AIN4) |
1105 BIT(ADV7182_INPUT_CVBS_AIN7) |
1106 BIT(ADV7182_INPUT_CVBS_AIN8) |
1107 BIT(ADV7182_INPUT_SVIDEO_AIN1_AIN2) |
1108 BIT(ADV7182_INPUT_SVIDEO_AIN3_AIN4) |
1109 BIT(ADV7182_INPUT_SVIDEO_AIN7_AIN8) |
1110 BIT(ADV7182_INPUT_DIFF_CVBS_AIN1_AIN2) |
1111 BIT(ADV7182_INPUT_DIFF_CVBS_AIN3_AIN4) |
1112 BIT(ADV7182_INPUT_DIFF_CVBS_AIN7_AIN8),
1113 .init = adv7182_init,
1114 .set_std = adv7182_set_std,
1115 .select_input = adv7182_select_input,
1116};
1117
f5dde49b
LPC
1118static int init_device(struct adv7180_state *state)
1119{
1120 int ret;
1121
1122 mutex_lock(&state->mutex);
1123
1124 adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
16dfe72f 1125 usleep_range(5000, 10000);
f5dde49b
LPC
1126
1127 ret = state->chip_info->init(state);
1128 if (ret)
3999e5d0 1129 goto out_unlock;
42752f7a 1130
f5dde49b
LPC
1131 ret = adv7180_program_std(state);
1132 if (ret)
1133 goto out_unlock;
42752f7a 1134
851a54ef
LPC
1135 adv7180_set_field_mode(state);
1136
42752f7a
RR
1137 /* register for interrupts */
1138 if (state->irq > 0) {
42752f7a 1139 /* config the Interrupt pin to be active low */
3999e5d0 1140 ret = adv7180_write(state, ADV7180_REG_ICONF1,
bca7ad1a
FV
1141 ADV7180_ICONF1_ACTIVE_LOW |
1142 ADV7180_ICONF1_PSYNC_ONLY);
42752f7a 1143 if (ret < 0)
3999e5d0 1144 goto out_unlock;
42752f7a 1145
3999e5d0 1146 ret = adv7180_write(state, ADV7180_REG_IMR1, 0);
42752f7a 1147 if (ret < 0)
3999e5d0 1148 goto out_unlock;
42752f7a 1149
3999e5d0 1150 ret = adv7180_write(state, ADV7180_REG_IMR2, 0);
42752f7a 1151 if (ret < 0)
3999e5d0 1152 goto out_unlock;
42752f7a
RR
1153
1154 /* enable AD change interrupts interrupts */
3999e5d0 1155 ret = adv7180_write(state, ADV7180_REG_IMR3,
bca7ad1a 1156 ADV7180_IRQ3_AD_CHANGE);
42752f7a 1157 if (ret < 0)
3999e5d0 1158 goto out_unlock;
42752f7a 1159
3999e5d0 1160 ret = adv7180_write(state, ADV7180_REG_IMR4, 0);
42752f7a 1161 if (ret < 0)
3999e5d0 1162 goto out_unlock;
6789cb52
RR
1163 }
1164
3999e5d0
LPC
1165out_unlock:
1166 mutex_unlock(&state->mutex);
df065b37 1167
df065b37 1168 return ret;
bca7ad1a
FV
1169}
1170
4c62e976
GKH
1171static int adv7180_probe(struct i2c_client *client,
1172 const struct i2c_device_id *id)
bca7ad1a
FV
1173{
1174 struct adv7180_state *state;
1175 struct v4l2_subdev *sd;
1176 int ret;
1177
1178 /* Check if the adapter supports the needed features */
1179 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1180 return -EIO;
1181
1182 v4l_info(client, "chip found @ 0x%02x (%s)\n",
1183 client->addr, client->adapter->name);
1184
c02b211d 1185 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
7657e064
FE
1186 if (state == NULL)
1187 return -ENOMEM;
bca7ad1a 1188
3999e5d0 1189 state->client = client;
851a54ef 1190 state->field = V4L2_FIELD_INTERLACED;
f5dde49b 1191 state->chip_info = (struct adv7180_chip_info *)id->driver_data;
3999e5d0 1192
b37135e3
LPC
1193 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
1194 state->csi_client = i2c_new_dummy(client->adapter,
1195 ADV7180_DEFAULT_CSI_I2C_ADDR);
1196 if (!state->csi_client)
1197 return -ENOMEM;
1198 }
1199
851a54ef
LPC
1200 if (state->chip_info->flags & ADV7180_FLAG_I2P) {
1201 state->vpp_client = i2c_new_dummy(client->adapter,
1202 ADV7180_DEFAULT_VPP_I2C_ADDR);
1203 if (!state->vpp_client) {
1204 ret = -ENOMEM;
1205 goto err_unregister_csi_client;
1206 }
1207 }
1208
bca7ad1a 1209 state->irq = client->irq;
bca7ad1a
FV
1210 mutex_init(&state->mutex);
1211 state->autodetect = true;
f5dde49b
LPC
1212 if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED)
1213 state->powered = true;
1214 else
1215 state->powered = false;
bca7ad1a
FV
1216 state->input = 0;
1217 sd = &state->sd;
1218 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
d5d51a82 1219 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
bca7ad1a 1220
c9fbeddd
FV
1221 ret = adv7180_init_controls(state);
1222 if (ret)
851a54ef 1223 goto err_unregister_vpp_client;
d5d51a82
LPC
1224
1225 state->pad.flags = MEDIA_PAD_FL_SOURCE;
4ca72efa 1226 sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER;
ab22e77c 1227 ret = media_entity_pads_init(&sd->entity, 1, &state->pad);
c9fbeddd
FV
1228 if (ret)
1229 goto err_free_ctrl;
fa5b7945 1230
d5d51a82
LPC
1231 ret = init_device(state);
1232 if (ret)
1233 goto err_media_entity_cleanup;
1234
fa5721d1
LPC
1235 if (state->irq) {
1236 ret = request_threaded_irq(client->irq, NULL, adv7180_irq,
f3e991d4
LPC
1237 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
1238 KBUILD_MODNAME, state);
fa5721d1 1239 if (ret)
d5d51a82 1240 goto err_media_entity_cleanup;
fa5721d1
LPC
1241 }
1242
fa5b7945
LPC
1243 ret = v4l2_async_register_subdev(sd);
1244 if (ret)
1245 goto err_free_irq;
1246
6789cb52 1247 return 0;
42752f7a 1248
fa5b7945
LPC
1249err_free_irq:
1250 if (state->irq > 0)
1251 free_irq(client->irq, state);
d5d51a82
LPC
1252err_media_entity_cleanup:
1253 media_entity_cleanup(&sd->entity);
c9fbeddd
FV
1254err_free_ctrl:
1255 adv7180_exit_controls(state);
851a54ef
LPC
1256err_unregister_vpp_client:
1257 if (state->chip_info->flags & ADV7180_FLAG_I2P)
1258 i2c_unregister_device(state->vpp_client);
b37135e3
LPC
1259err_unregister_csi_client:
1260 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
1261 i2c_unregister_device(state->csi_client);
297a0ae3 1262 mutex_destroy(&state->mutex);
42752f7a 1263 return ret;
6789cb52
RR
1264}
1265
4c62e976 1266static int adv7180_remove(struct i2c_client *client)
6789cb52
RR
1267{
1268 struct v4l2_subdev *sd = i2c_get_clientdata(client);
42752f7a
RR
1269 struct adv7180_state *state = to_state(sd);
1270
fa5b7945
LPC
1271 v4l2_async_unregister_subdev(sd);
1272
0c25534d 1273 if (state->irq > 0)
42752f7a 1274 free_irq(client->irq, state);
6789cb52 1275
d5d51a82 1276 media_entity_cleanup(&sd->entity);
b13f4af2 1277 adv7180_exit_controls(state);
b37135e3 1278
851a54ef
LPC
1279 if (state->chip_info->flags & ADV7180_FLAG_I2P)
1280 i2c_unregister_device(state->vpp_client);
b37135e3
LPC
1281 if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
1282 i2c_unregister_device(state->csi_client);
1283
297a0ae3 1284 mutex_destroy(&state->mutex);
b37135e3 1285
6789cb52
RR
1286 return 0;
1287}
1288
1289static const struct i2c_device_id adv7180_id[] = {
f5dde49b 1290 { "adv7180", (kernel_ulong_t)&adv7180_info },
c5ef8f8c 1291 { "adv7182", (kernel_ulong_t)&adv7182_info },
bf7dcb80 1292 { "adv7280", (kernel_ulong_t)&adv7280_info },
b37135e3 1293 { "adv7280-m", (kernel_ulong_t)&adv7280_m_info },
bf7dcb80 1294 { "adv7281", (kernel_ulong_t)&adv7281_info },
b37135e3
LPC
1295 { "adv7281-m", (kernel_ulong_t)&adv7281_m_info },
1296 { "adv7281-ma", (kernel_ulong_t)&adv7281_ma_info },
851a54ef
LPC
1297 { "adv7282", (kernel_ulong_t)&adv7282_info },
1298 { "adv7282-m", (kernel_ulong_t)&adv7282_m_info },
6789cb52
RR
1299 {},
1300};
f5dde49b 1301MODULE_DEVICE_TABLE(i2c, adv7180_id);
6789cb52 1302
cc1088dc
LPC
1303#ifdef CONFIG_PM_SLEEP
1304static int adv7180_suspend(struct device *dev)
bca7ad1a 1305{
cc1088dc 1306 struct i2c_client *client = to_i2c_client(dev);
e246c333
LPC
1307 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1308 struct adv7180_state *state = to_state(sd);
bca7ad1a 1309
3999e5d0 1310 return adv7180_set_power(state, false);
bca7ad1a
FV
1311}
1312
cc1088dc 1313static int adv7180_resume(struct device *dev)
bca7ad1a 1314{
cc1088dc 1315 struct i2c_client *client = to_i2c_client(dev);
bca7ad1a
FV
1316 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1317 struct adv7180_state *state = to_state(sd);
1318 int ret;
1319
3999e5d0 1320 ret = init_device(state);
bca7ad1a
FV
1321 if (ret < 0)
1322 return ret;
c18818e9
LPC
1323
1324 ret = adv7180_set_power(state, state->powered);
1325 if (ret)
1326 return ret;
1327
bca7ad1a
FV
1328 return 0;
1329}
cc1088dc
LPC
1330
1331static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
1332#define ADV7180_PM_OPS (&adv7180_pm_ops)
1333
1334#else
1335#define ADV7180_PM_OPS NULL
bca7ad1a
FV
1336#endif
1337
250121d3
BD
1338#ifdef CONFIG_OF
1339static const struct of_device_id adv7180_of_id[] = {
1340 { .compatible = "adi,adv7180", },
1341 { },
1342};
1343
1344MODULE_DEVICE_TABLE(of, adv7180_of_id);
1345#endif
1346
6789cb52
RR
1347static struct i2c_driver adv7180_driver = {
1348 .driver = {
c9fbeddd 1349 .name = KBUILD_MODNAME,
cc1088dc 1350 .pm = ADV7180_PM_OPS,
250121d3 1351 .of_match_table = of_match_ptr(adv7180_of_id),
bca7ad1a
FV
1352 },
1353 .probe = adv7180_probe,
4c62e976 1354 .remove = adv7180_remove,
bca7ad1a 1355 .id_table = adv7180_id,
6789cb52
RR
1356};
1357
c6e8d86f 1358module_i2c_driver(adv7180_driver);
6789cb52
RR
1359
1360MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
1361MODULE_AUTHOR("Mocean Laboratories");
1362MODULE_LICENSE("GPL v2");