aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/media/i2c/adv7604.txt70
-rw-r--r--Documentation/devicetree/bindings/media/renesas,vsp1.txt43
-rw-r--r--drivers/media/i2c/adv7604.c1464
-rw-r--r--drivers/media/platform/vsp1/Makefile2
-rw-r--r--drivers/media/platform/vsp1/vsp1.h3
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c395
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.h39
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c101
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c57
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h24
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c7
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c1
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c1
-rw-r--r--drivers/media/platform/vsp1/vsp1_regs.h98
-rw-r--r--drivers/media/platform/vsp1/vsp1_rpf.c7
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h4
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c1
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c4
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c26
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_wpf.c13
-rw-r--r--include/media/adv7604.h122
-rw-r--r--include/media/v4l2-subdev.h4
23 files changed, 1893 insertions, 594 deletions
diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
new file mode 100644
index 000000000000..c27cede3bd68
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt
@@ -0,0 +1,70 @@
1* Analog Devices ADV7604/11 video decoder with HDMI receiver
2
3The ADV7604 and ADV7611 are multiformat video decoders with an integrated HDMI
4receiver. The ADV7604 has four multiplexed HDMI inputs and one analog input,
5and the ADV7611 has one HDMI input and no analog input.
6
7These device tree bindings support the ADV7611 only at the moment.
8
9Required Properties:
10
11 - compatible: Must contain one of the following
12 - "adi,adv7611" for the ADV7611
13
14 - reg: I2C slave address
15
16 - hpd-gpios: References to the GPIOs that control the HDMI hot-plug
17 detection pins, one per HDMI input. The active flag indicates the GPIO
18 level that enables hot-plug detection.
19
20The device node must contain one 'port' child node per device input and output
21port, in accordance with the video interface bindings defined in
22Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes
23are numbered as follows.
24
25 Port ADV7611
26------------------------------------------------------------
27 HDMI 0
28 Digital output 1
29
30The digital output port node must contain at least one endpoint.
31
32Optional Properties:
33
34 - reset-gpios: Reference to the GPIO connected to the device's reset pin.
35
36Optional Endpoint Properties:
37
38 The following three properties are defined in video-interfaces.txt and are
39 valid for source endpoints only.
40
41 - hsync-active: Horizontal synchronization polarity. Defaults to active low.
42 - vsync-active: Vertical synchronization polarity. Defaults to active low.
43 - pclk-sample: Pixel clock polarity. Defaults to output on the falling edge.
44
45 If none of hsync-active, vsync-active and pclk-sample is specified the
46 endpoint will use embedded BT.656 synchronization.
47
48
49Example:
50
51 hdmi_receiver@4c {
52 compatible = "adi,adv7611";
53 reg = <0x4c>;
54
55 reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>;
56 hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>;
57
58 #address-cells = <1>;
59 #size-cells = <0>;
60
61 port@0 {
62 reg = <0>;
63 };
64 port@1 {
65 reg = <1>;
66 hdmi_in: endpoint {
67 remote-endpoint = <&ccdc_in>;
68 };
69 };
70 };
diff --git a/Documentation/devicetree/bindings/media/renesas,vsp1.txt b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
new file mode 100644
index 000000000000..87fe08abf36d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/renesas,vsp1.txt
@@ -0,0 +1,43 @@
1* Renesas VSP1 Video Processing Engine
2
3The VSP1 is a video processing engine that supports up-/down-scaling, alpha
4blending, color space conversion and various other image processing features.
5It can be found in the Renesas R-Car second generation SoCs.
6
7Required properties:
8
9 - compatible: Must contain "renesas,vsp1"
10
11 - reg: Base address and length of the registers block for the VSP1.
12 - interrupts: VSP1 interrupt specifier.
13 - clocks: A phandle + clock-specifier pair for the VSP1 functional clock.
14
15 - renesas,#rpf: Number of Read Pixel Formatter (RPF) modules in the VSP1.
16 - renesas,#uds: Number of Up Down Scaler (UDS) modules in the VSP1.
17 - renesas,#wpf: Number of Write Pixel Formatter (WPF) modules in the VSP1.
18
19
20Optional properties:
21
22 - renesas,has-lif: Boolean, indicates that the LCD Interface (LIF) module is
23 available.
24 - renesas,has-lut: Boolean, indicates that the Look Up Table (LUT) module is
25 available.
26 - renesas,has-sru: Boolean, indicates that the Super Resolution Unit (SRU)
27 module is available.
28
29
30Example: R8A7790 (R-Car H2) VSP1-S node
31
32 vsp1@fe928000 {
33 compatible = "renesas,vsp1";
34 reg = <0 0xfe928000 0 0x8000>;
35 interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
36 clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
37
38 renesas,has-lut;
39 renesas,has-sru;
40 renesas,#rpf = <5>;
41 renesas,#uds = <3>;
42 renesas,#wpf = <4>;
43 };
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 338baa4c23ef..1778d320272e 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -27,19 +27,21 @@
27 * REF_03 - Analog devices, ADV7604, Hardware Manual, Rev. F, August 2010 27 * REF_03 - Analog devices, ADV7604, Hardware Manual, Rev. F, August 2010
28 */ 28 */
29 29
30 30#include <linux/delay.h>
31#include <linux/gpio/consumer.h>
32#include <linux/i2c.h>
31#include <linux/kernel.h> 33#include <linux/kernel.h>
32#include <linux/module.h> 34#include <linux/module.h>
33#include <linux/slab.h> 35#include <linux/slab.h>
34#include <linux/i2c.h> 36#include <linux/v4l2-dv-timings.h>
35#include <linux/delay.h>
36#include <linux/videodev2.h> 37#include <linux/videodev2.h>
37#include <linux/workqueue.h> 38#include <linux/workqueue.h>
38#include <linux/v4l2-dv-timings.h> 39
39#include <media/v4l2-device.h> 40#include <media/adv7604.h>
40#include <media/v4l2-ctrls.h> 41#include <media/v4l2-ctrls.h>
42#include <media/v4l2-device.h>
41#include <media/v4l2-dv-timings.h> 43#include <media/v4l2-dv-timings.h>
42#include <media/adv7604.h> 44#include <media/v4l2-of.h>
43 45
44static int debug; 46static int debug;
45module_param(debug, int, 0644); 47module_param(debug, int, 0644);
@@ -53,6 +55,76 @@ MODULE_LICENSE("GPL");
53/* ADV7604 system clock frequency */ 55/* ADV7604 system clock frequency */
54#define ADV7604_fsc (28636360) 56#define ADV7604_fsc (28636360)
55 57
58#define ADV7604_RGB_OUT (1 << 1)
59
60#define ADV7604_OP_FORMAT_SEL_8BIT (0 << 0)
61#define ADV7604_OP_FORMAT_SEL_10BIT (1 << 0)
62#define ADV7604_OP_FORMAT_SEL_12BIT (2 << 0)
63
64#define ADV7604_OP_MODE_SEL_SDR_422 (0 << 5)
65#define ADV7604_OP_MODE_SEL_DDR_422 (1 << 5)
66#define ADV7604_OP_MODE_SEL_SDR_444 (2 << 5)
67#define ADV7604_OP_MODE_SEL_DDR_444 (3 << 5)
68#define ADV7604_OP_MODE_SEL_SDR_422_2X (4 << 5)
69#define ADV7604_OP_MODE_SEL_ADI_CM (5 << 5)
70
71#define ADV7604_OP_CH_SEL_GBR (0 << 5)
72#define ADV7604_OP_CH_SEL_GRB (1 << 5)
73#define ADV7604_OP_CH_SEL_BGR (2 << 5)
74#define ADV7604_OP_CH_SEL_RGB (3 << 5)
75#define ADV7604_OP_CH_SEL_BRG (4 << 5)
76#define ADV7604_OP_CH_SEL_RBG (5 << 5)
77
78#define ADV7604_OP_SWAP_CB_CR (1 << 0)
79
80enum adv7604_type {
81 ADV7604,
82 ADV7611,
83};
84
85struct adv7604_reg_seq {
86 unsigned int reg;
87 u8 val;
88};
89
90struct adv7604_format_info {
91 enum v4l2_mbus_pixelcode code;
92 u8 op_ch_sel;
93 bool rgb_out;
94 bool swap_cb_cr;
95 u8 op_format_sel;
96};
97
98struct adv7604_chip_info {
99 enum adv7604_type type;
100
101 bool has_afe;
102 unsigned int max_port;
103 unsigned int num_dv_ports;
104
105 unsigned int edid_enable_reg;
106 unsigned int edid_status_reg;
107 unsigned int lcf_reg;
108
109 unsigned int cable_det_mask;
110 unsigned int tdms_lock_mask;
111 unsigned int fmt_change_digital_mask;
112
113 const struct adv7604_format_info *formats;
114 unsigned int nformats;
115
116 void (*set_termination)(struct v4l2_subdev *sd, bool enable);
117 void (*setup_irqs)(struct v4l2_subdev *sd);
118 unsigned int (*read_hdmi_pixelclock)(struct v4l2_subdev *sd);
119 unsigned int (*read_cable_det)(struct v4l2_subdev *sd);
120
121 /* 0 = AFE, 1 = HDMI */
122 const struct adv7604_reg_seq *recommended_settings[2];
123 unsigned int num_recommended_settings[2];
124
125 unsigned long page_mask;
126};
127
56/* 128/*
57 ********************************************************************** 129 **********************************************************************
58 * 130 *
@@ -60,13 +132,24 @@ MODULE_LICENSE("GPL");
60 * 132 *
61 ********************************************************************** 133 **********************************************************************
62 */ 134 */
135
63struct adv7604_state { 136struct adv7604_state {
137 const struct adv7604_chip_info *info;
64 struct adv7604_platform_data pdata; 138 struct adv7604_platform_data pdata;
139
140 struct gpio_desc *hpd_gpio[4];
141
65 struct v4l2_subdev sd; 142 struct v4l2_subdev sd;
66 struct media_pad pad; 143 struct media_pad pads[ADV7604_PAD_MAX];
144 unsigned int source_pad;
145
67 struct v4l2_ctrl_handler hdl; 146 struct v4l2_ctrl_handler hdl;
68 enum adv7604_input_port selected_input; 147
148 enum adv7604_pad selected_input;
149
69 struct v4l2_dv_timings timings; 150 struct v4l2_dv_timings timings;
151 const struct adv7604_format_info *format;
152
70 struct { 153 struct {
71 u8 edid[256]; 154 u8 edid[256];
72 u32 present; 155 u32 present;
@@ -80,18 +163,7 @@ struct adv7604_state {
80 bool restart_stdi_once; 163 bool restart_stdi_once;
81 164
82 /* i2c clients */ 165 /* i2c clients */
83 struct i2c_client *i2c_avlink; 166 struct i2c_client *i2c_clients[ADV7604_PAGE_MAX];
84 struct i2c_client *i2c_cec;
85 struct i2c_client *i2c_infoframe;
86 struct i2c_client *i2c_esdp;
87 struct i2c_client *i2c_dpp;
88 struct i2c_client *i2c_afe;
89 struct i2c_client *i2c_repeater;
90 struct i2c_client *i2c_edid;
91 struct i2c_client *i2c_hdmi;
92 struct i2c_client *i2c_test;
93 struct i2c_client *i2c_cp;
94 struct i2c_client *i2c_vdp;
95 167
96 /* controls */ 168 /* controls */
97 struct v4l2_ctrl *detect_tx_5v_ctrl; 169 struct v4l2_ctrl *detect_tx_5v_ctrl;
@@ -101,6 +173,11 @@ struct adv7604_state {
101 struct v4l2_ctrl *rgb_quantization_range_ctrl; 173 struct v4l2_ctrl *rgb_quantization_range_ctrl;
102}; 174};
103 175
176static bool adv7604_has_afe(struct adv7604_state *state)
177{
178 return state->info->has_afe;
179}
180
104/* Supported CEA and DMT timings */ 181/* Supported CEA and DMT timings */
105static const struct v4l2_dv_timings adv7604_timings[] = { 182static const struct v4l2_dv_timings adv7604_timings[] = {
106 V4L2_DV_BT_CEA_720X480P59_94, 183 V4L2_DV_BT_CEA_720X480P59_94,
@@ -256,11 +333,6 @@ static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
256 return container_of(sd, struct adv7604_state, sd); 333 return container_of(sd, struct adv7604_state, sd);
257} 334}
258 335
259static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
260{
261 return &container_of(ctrl->handler, struct adv7604_state, hdl)->sd;
262}
263
264static inline unsigned hblanking(const struct v4l2_bt_timings *t) 336static inline unsigned hblanking(const struct v4l2_bt_timings *t)
265{ 337{
266 return V4L2_DV_BT_BLANKING_WIDTH(t); 338 return V4L2_DV_BT_BLANKING_WIDTH(t);
@@ -298,14 +370,18 @@ static s32 adv_smbus_read_byte_data_check(struct i2c_client *client,
298 return -EIO; 370 return -EIO;
299} 371}
300 372
301static s32 adv_smbus_read_byte_data(struct i2c_client *client, u8 command) 373static s32 adv_smbus_read_byte_data(struct adv7604_state *state,
374 enum adv7604_page page, u8 command)
302{ 375{
303 return adv_smbus_read_byte_data_check(client, command, true); 376 return adv_smbus_read_byte_data_check(state->i2c_clients[page],
377 command, true);
304} 378}
305 379
306static s32 adv_smbus_write_byte_data(struct i2c_client *client, 380static s32 adv_smbus_write_byte_data(struct adv7604_state *state,
307 u8 command, u8 value) 381 enum adv7604_page page, u8 command,
382 u8 value)
308{ 383{
384 struct i2c_client *client = state->i2c_clients[page];
309 union i2c_smbus_data data; 385 union i2c_smbus_data data;
310 int err; 386 int err;
311 int i; 387 int i;
@@ -325,9 +401,11 @@ static s32 adv_smbus_write_byte_data(struct i2c_client *client,
325 return err; 401 return err;
326} 402}
327 403
328static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client, 404static s32 adv_smbus_write_i2c_block_data(struct adv7604_state *state,
329 u8 command, unsigned length, const u8 *values) 405 enum adv7604_page page, u8 command,
406 unsigned length, const u8 *values)
330{ 407{
408 struct i2c_client *client = state->i2c_clients[page];
331 union i2c_smbus_data data; 409 union i2c_smbus_data data;
332 410
333 if (length > I2C_SMBUS_BLOCK_MAX) 411 if (length > I2C_SMBUS_BLOCK_MAX)
@@ -343,149 +421,150 @@ static s32 adv_smbus_write_i2c_block_data(struct i2c_client *client,
343 421
344static inline int io_read(struct v4l2_subdev *sd, u8 reg) 422static inline int io_read(struct v4l2_subdev *sd, u8 reg)
345{ 423{
346 struct i2c_client *client = v4l2_get_subdevdata(sd); 424 struct adv7604_state *state = to_state(sd);
347 425
348 return adv_smbus_read_byte_data(client, reg); 426 return adv_smbus_read_byte_data(state, ADV7604_PAGE_IO, reg);
349} 427}
350 428
351static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val) 429static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
352{ 430{
353 struct i2c_client *client = v4l2_get_subdevdata(sd); 431 struct adv7604_state *state = to_state(sd);
354 432
355 return adv_smbus_write_byte_data(client, reg, val); 433 return adv_smbus_write_byte_data(state, ADV7604_PAGE_IO, reg, val);
356} 434}
357 435
358static inline int io_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 436static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
359{ 437{
360 return io_write(sd, reg, (io_read(sd, reg) & mask) | val); 438 return io_write(sd, reg, (io_read(sd, reg) & ~mask) | val);
361} 439}
362 440
363static inline int avlink_read(struct v4l2_subdev *sd, u8 reg) 441static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
364{ 442{
365 struct adv7604_state *state = to_state(sd); 443 struct adv7604_state *state = to_state(sd);
366 444
367 return adv_smbus_read_byte_data(state->i2c_avlink, reg); 445 return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg);
368} 446}
369 447
370static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val) 448static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
371{ 449{
372 struct adv7604_state *state = to_state(sd); 450 struct adv7604_state *state = to_state(sd);
373 451
374 return adv_smbus_write_byte_data(state->i2c_avlink, reg, val); 452 return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val);
375} 453}
376 454
377static inline int cec_read(struct v4l2_subdev *sd, u8 reg) 455static inline int cec_read(struct v4l2_subdev *sd, u8 reg)
378{ 456{
379 struct adv7604_state *state = to_state(sd); 457 struct adv7604_state *state = to_state(sd);
380 458
381 return adv_smbus_read_byte_data(state->i2c_cec, reg); 459 return adv_smbus_read_byte_data(state, ADV7604_PAGE_CEC, reg);
382} 460}
383 461
384static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val) 462static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
385{ 463{
386 struct adv7604_state *state = to_state(sd); 464 struct adv7604_state *state = to_state(sd);
387 465
388 return adv_smbus_write_byte_data(state->i2c_cec, reg, val); 466 return adv_smbus_write_byte_data(state, ADV7604_PAGE_CEC, reg, val);
389} 467}
390 468
391static inline int cec_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 469static inline int cec_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
392{ 470{
393 return cec_write(sd, reg, (cec_read(sd, reg) & mask) | val); 471 return cec_write(sd, reg, (cec_read(sd, reg) & ~mask) | val);
394} 472}
395 473
396static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg) 474static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
397{ 475{
398 struct adv7604_state *state = to_state(sd); 476 struct adv7604_state *state = to_state(sd);
399 477
400 return adv_smbus_read_byte_data(state->i2c_infoframe, reg); 478 return adv_smbus_read_byte_data(state, ADV7604_PAGE_INFOFRAME, reg);
401} 479}
402 480
403static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val) 481static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
404{ 482{
405 struct adv7604_state *state = to_state(sd); 483 struct adv7604_state *state = to_state(sd);
406 484
407 return adv_smbus_write_byte_data(state->i2c_infoframe, reg, val); 485 return adv_smbus_write_byte_data(state, ADV7604_PAGE_INFOFRAME,
486 reg, val);
408} 487}
409 488
410static inline int esdp_read(struct v4l2_subdev *sd, u8 reg) 489static inline int esdp_read(struct v4l2_subdev *sd, u8 reg)
411{ 490{
412 struct adv7604_state *state = to_state(sd); 491 struct adv7604_state *state = to_state(sd);
413 492
414 return adv_smbus_read_byte_data(state->i2c_esdp, reg); 493 return adv_smbus_read_byte_data(state, ADV7604_PAGE_ESDP, reg);
415} 494}
416 495
417static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 496static inline int esdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
418{ 497{
419 struct adv7604_state *state = to_state(sd); 498 struct adv7604_state *state = to_state(sd);
420 499
421 return adv_smbus_write_byte_data(state->i2c_esdp, reg, val); 500 return adv_smbus_write_byte_data(state, ADV7604_PAGE_ESDP, reg, val);
422} 501}
423 502
424static inline int dpp_read(struct v4l2_subdev *sd, u8 reg) 503static inline int dpp_read(struct v4l2_subdev *sd, u8 reg)
425{ 504{
426 struct adv7604_state *state = to_state(sd); 505 struct adv7604_state *state = to_state(sd);
427 506
428 return adv_smbus_read_byte_data(state->i2c_dpp, reg); 507 return adv_smbus_read_byte_data(state, ADV7604_PAGE_DPP, reg);
429} 508}
430 509
431static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 510static inline int dpp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
432{ 511{
433 struct adv7604_state *state = to_state(sd); 512 struct adv7604_state *state = to_state(sd);
434 513
435 return adv_smbus_write_byte_data(state->i2c_dpp, reg, val); 514 return adv_smbus_write_byte_data(state, ADV7604_PAGE_DPP, reg, val);
436} 515}
437 516
438static inline int afe_read(struct v4l2_subdev *sd, u8 reg) 517static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
439{ 518{
440 struct adv7604_state *state = to_state(sd); 519 struct adv7604_state *state = to_state(sd);
441 520
442 return adv_smbus_read_byte_data(state->i2c_afe, reg); 521 return adv_smbus_read_byte_data(state, ADV7604_PAGE_AFE, reg);
443} 522}
444 523
445static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val) 524static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
446{ 525{
447 struct adv7604_state *state = to_state(sd); 526 struct adv7604_state *state = to_state(sd);
448 527
449 return adv_smbus_write_byte_data(state->i2c_afe, reg, val); 528 return adv_smbus_write_byte_data(state, ADV7604_PAGE_AFE, reg, val);
450} 529}
451 530
452static inline int rep_read(struct v4l2_subdev *sd, u8 reg) 531static inline int rep_read(struct v4l2_subdev *sd, u8 reg)
453{ 532{
454 struct adv7604_state *state = to_state(sd); 533 struct adv7604_state *state = to_state(sd);
455 534
456 return adv_smbus_read_byte_data(state->i2c_repeater, reg); 535 return adv_smbus_read_byte_data(state, ADV7604_PAGE_REP, reg);
457} 536}
458 537
459static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val) 538static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val)
460{ 539{
461 struct adv7604_state *state = to_state(sd); 540 struct adv7604_state *state = to_state(sd);
462 541
463 return adv_smbus_write_byte_data(state->i2c_repeater, reg, val); 542 return adv_smbus_write_byte_data(state, ADV7604_PAGE_REP, reg, val);
464} 543}
465 544
466static inline int rep_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 545static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
467{ 546{
468 return rep_write(sd, reg, (rep_read(sd, reg) & mask) | val); 547 return rep_write(sd, reg, (rep_read(sd, reg) & ~mask) | val);
469} 548}
470 549
471static inline int edid_read(struct v4l2_subdev *sd, u8 reg) 550static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
472{ 551{
473 struct adv7604_state *state = to_state(sd); 552 struct adv7604_state *state = to_state(sd);
474 553
475 return adv_smbus_read_byte_data(state->i2c_edid, reg); 554 return adv_smbus_read_byte_data(state, ADV7604_PAGE_EDID, reg);
476} 555}
477 556
478static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val) 557static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
479{ 558{
480 struct adv7604_state *state = to_state(sd); 559 struct adv7604_state *state = to_state(sd);
481 560
482 return adv_smbus_write_byte_data(state->i2c_edid, reg, val); 561 return adv_smbus_write_byte_data(state, ADV7604_PAGE_EDID, reg, val);
483} 562}
484 563
485static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val) 564static inline int edid_read_block(struct v4l2_subdev *sd, unsigned len, u8 *val)
486{ 565{
487 struct adv7604_state *state = to_state(sd); 566 struct adv7604_state *state = to_state(sd);
488 struct i2c_client *client = state->i2c_edid; 567 struct i2c_client *client = state->i2c_clients[ADV7604_PAGE_EDID];
489 u8 msgbuf0[1] = { 0 }; 568 u8 msgbuf0[1] = { 0 };
490 u8 msgbuf1[256]; 569 u8 msgbuf1[256];
491 struct i2c_msg msg[2] = { 570 struct i2c_msg msg[2] = {
@@ -518,11 +597,25 @@ static inline int edid_write_block(struct v4l2_subdev *sd,
518 v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len); 597 v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len);
519 598
520 for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX) 599 for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX)
521 err = adv_smbus_write_i2c_block_data(state->i2c_edid, i, 600 err = adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_EDID,
522 I2C_SMBUS_BLOCK_MAX, val + i); 601 i, I2C_SMBUS_BLOCK_MAX, val + i);
523 return err; 602 return err;
524} 603}
525 604
605static void adv7604_set_hpd(struct adv7604_state *state, unsigned int hpd)
606{
607 unsigned int i;
608
609 for (i = 0; i < state->info->num_dv_ports; ++i) {
610 if (IS_ERR(state->hpd_gpio[i]))
611 continue;
612
613 gpiod_set_value_cansleep(state->hpd_gpio[i], hpd & BIT(i));
614 }
615
616 v4l2_subdev_notify(&state->sd, ADV7604_HOTPLUG, &hpd);
617}
618
526static void adv7604_delayed_work_enable_hotplug(struct work_struct *work) 619static void adv7604_delayed_work_enable_hotplug(struct work_struct *work)
527{ 620{
528 struct delayed_work *dwork = to_delayed_work(work); 621 struct delayed_work *dwork = to_delayed_work(work);
@@ -532,73 +625,210 @@ static void adv7604_delayed_work_enable_hotplug(struct work_struct *work)
532 625
533 v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__); 626 v4l2_dbg(2, debug, sd, "%s: enable hotplug\n", __func__);
534 627
535 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&state->edid.present); 628 adv7604_set_hpd(state, state->edid.present);
536} 629}
537 630
538static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg) 631static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
539{ 632{
540 struct adv7604_state *state = to_state(sd); 633 struct adv7604_state *state = to_state(sd);
541 634
542 return adv_smbus_read_byte_data(state->i2c_hdmi, reg); 635 return adv_smbus_read_byte_data(state, ADV7604_PAGE_HDMI, reg);
636}
637
638static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
639{
640 return ((hdmi_read(sd, reg) << 8) | hdmi_read(sd, reg + 1)) & mask;
543} 641}
544 642
545static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val) 643static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
546{ 644{
547 struct adv7604_state *state = to_state(sd); 645 struct adv7604_state *state = to_state(sd);
548 646
549 return adv_smbus_write_byte_data(state->i2c_hdmi, reg, val); 647 return adv_smbus_write_byte_data(state, ADV7604_PAGE_HDMI, reg, val);
550} 648}
551 649
552static inline int hdmi_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 650static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
553{ 651{
554 return hdmi_write(sd, reg, (hdmi_read(sd, reg) & mask) | val); 652 return hdmi_write(sd, reg, (hdmi_read(sd, reg) & ~mask) | val);
555} 653}
556 654
557static inline int test_read(struct v4l2_subdev *sd, u8 reg) 655static inline int test_read(struct v4l2_subdev *sd, u8 reg)
558{ 656{
559 struct adv7604_state *state = to_state(sd); 657 struct adv7604_state *state = to_state(sd);
560 658
561 return adv_smbus_read_byte_data(state->i2c_test, reg); 659 return adv_smbus_read_byte_data(state, ADV7604_PAGE_TEST, reg);
562} 660}
563 661
564static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val) 662static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
565{ 663{
566 struct adv7604_state *state = to_state(sd); 664 struct adv7604_state *state = to_state(sd);
567 665
568 return adv_smbus_write_byte_data(state->i2c_test, reg, val); 666 return adv_smbus_write_byte_data(state, ADV7604_PAGE_TEST, reg, val);
569} 667}
570 668
571static inline int cp_read(struct v4l2_subdev *sd, u8 reg) 669static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
572{ 670{
573 struct adv7604_state *state = to_state(sd); 671 struct adv7604_state *state = to_state(sd);
574 672
575 return adv_smbus_read_byte_data(state->i2c_cp, reg); 673 return adv_smbus_read_byte_data(state, ADV7604_PAGE_CP, reg);
674}
675
676static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
677{
678 return ((cp_read(sd, reg) << 8) | cp_read(sd, reg + 1)) & mask;
576} 679}
577 680
578static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 681static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
579{ 682{
580 struct adv7604_state *state = to_state(sd); 683 struct adv7604_state *state = to_state(sd);
581 684
582 return adv_smbus_write_byte_data(state->i2c_cp, reg, val); 685 return adv_smbus_write_byte_data(state, ADV7604_PAGE_CP, reg, val);
583} 686}
584 687
585static inline int cp_write_and_or(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val) 688static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
586{ 689{
587 return cp_write(sd, reg, (cp_read(sd, reg) & mask) | val); 690 return cp_write(sd, reg, (cp_read(sd, reg) & ~mask) | val);
588} 691}
589 692
590static inline int vdp_read(struct v4l2_subdev *sd, u8 reg) 693static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
591{ 694{
592 struct adv7604_state *state = to_state(sd); 695 struct adv7604_state *state = to_state(sd);
593 696
594 return adv_smbus_read_byte_data(state->i2c_vdp, reg); 697 return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg);
595} 698}
596 699
597static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val) 700static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
598{ 701{
599 struct adv7604_state *state = to_state(sd); 702 struct adv7604_state *state = to_state(sd);
600 703
601 return adv_smbus_write_byte_data(state->i2c_vdp, reg, val); 704 return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val);
705}
706
707#define ADV7604_REG(page, offset) (((page) << 8) | (offset))
708#define ADV7604_REG_SEQ_TERM 0xffff
709
710#ifdef CONFIG_VIDEO_ADV_DEBUG
711static int adv7604_read_reg(struct v4l2_subdev *sd, unsigned int reg)
712{
713 struct adv7604_state *state = to_state(sd);
714 unsigned int page = reg >> 8;
715
716 if (!(BIT(page) & state->info->page_mask))
717 return -EINVAL;
718
719 reg &= 0xff;
720
721 return adv_smbus_read_byte_data(state, page, reg);
722}
723#endif
724
725static int adv7604_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val)
726{
727 struct adv7604_state *state = to_state(sd);
728 unsigned int page = reg >> 8;
729
730 if (!(BIT(page) & state->info->page_mask))
731 return -EINVAL;
732
733 reg &= 0xff;
734
735 return adv_smbus_write_byte_data(state, page, reg, val);
736}
737
738static void adv7604_write_reg_seq(struct v4l2_subdev *sd,
739 const struct adv7604_reg_seq *reg_seq)
740{
741 unsigned int i;
742
743 for (i = 0; reg_seq[i].reg != ADV7604_REG_SEQ_TERM; i++)
744 adv7604_write_reg(sd, reg_seq[i].reg, reg_seq[i].val);
745}
746
747/* -----------------------------------------------------------------------------
748 * Format helpers
749 */
750
751static const struct adv7604_format_info adv7604_formats[] = {
752 { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false,
753 ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT },
754 { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false,
755 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT },
756 { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true,
757 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT },
758 { V4L2_MBUS_FMT_YUYV10_2X10, ADV7604_OP_CH_SEL_RGB, false, false,
759 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT },
760 { V4L2_MBUS_FMT_YVYU10_2X10, ADV7604_OP_CH_SEL_RGB, false, true,
761 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_10BIT },
762 { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false,
763 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT },
764 { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true,
765 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT },
766 { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false,
767 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
768 { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true,
769 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
770 { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false,
771 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
772 { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true,
773 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
774 { V4L2_MBUS_FMT_UYVY10_1X20, ADV7604_OP_CH_SEL_RBG, false, false,
775 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT },
776 { V4L2_MBUS_FMT_VYUY10_1X20, ADV7604_OP_CH_SEL_RBG, false, true,
777 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT },
778 { V4L2_MBUS_FMT_YUYV10_1X20, ADV7604_OP_CH_SEL_RGB, false, false,
779 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT },
780 { V4L2_MBUS_FMT_YVYU10_1X20, ADV7604_OP_CH_SEL_RGB, false, true,
781 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_10BIT },
782 { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false,
783 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
784 { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true,
785 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
786 { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false,
787 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
788 { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true,
789 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
790};
791
792static const struct adv7604_format_info adv7611_formats[] = {
793 { V4L2_MBUS_FMT_RGB888_1X24, ADV7604_OP_CH_SEL_RGB, true, false,
794 ADV7604_OP_MODE_SEL_SDR_444 | ADV7604_OP_FORMAT_SEL_8BIT },
795 { V4L2_MBUS_FMT_YUYV8_2X8, ADV7604_OP_CH_SEL_RGB, false, false,
796 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT },
797 { V4L2_MBUS_FMT_YVYU8_2X8, ADV7604_OP_CH_SEL_RGB, false, true,
798 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_8BIT },
799 { V4L2_MBUS_FMT_YUYV12_2X12, ADV7604_OP_CH_SEL_RGB, false, false,
800 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT },
801 { V4L2_MBUS_FMT_YVYU12_2X12, ADV7604_OP_CH_SEL_RGB, false, true,
802 ADV7604_OP_MODE_SEL_SDR_422 | ADV7604_OP_FORMAT_SEL_12BIT },
803 { V4L2_MBUS_FMT_UYVY8_1X16, ADV7604_OP_CH_SEL_RBG, false, false,
804 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
805 { V4L2_MBUS_FMT_VYUY8_1X16, ADV7604_OP_CH_SEL_RBG, false, true,
806 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
807 { V4L2_MBUS_FMT_YUYV8_1X16, ADV7604_OP_CH_SEL_RGB, false, false,
808 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
809 { V4L2_MBUS_FMT_YVYU8_1X16, ADV7604_OP_CH_SEL_RGB, false, true,
810 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_8BIT },
811 { V4L2_MBUS_FMT_UYVY12_1X24, ADV7604_OP_CH_SEL_RBG, false, false,
812 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
813 { V4L2_MBUS_FMT_VYUY12_1X24, ADV7604_OP_CH_SEL_RBG, false, true,
814 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
815 { V4L2_MBUS_FMT_YUYV12_1X24, ADV7604_OP_CH_SEL_RGB, false, false,
816 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
817 { V4L2_MBUS_FMT_YVYU12_1X24, ADV7604_OP_CH_SEL_RGB, false, true,
818 ADV7604_OP_MODE_SEL_SDR_422_2X | ADV7604_OP_FORMAT_SEL_12BIT },
819};
820
821static const struct adv7604_format_info *
822adv7604_format_info(struct adv7604_state *state, enum v4l2_mbus_pixelcode code)
823{
824 unsigned int i;
825
826 for (i = 0; i < state->info->nformats; ++i) {
827 if (state->info->formats[i].code == code)
828 return &state->info->formats[i];
829 }
830
831 return NULL;
602} 832}
603 833
604/* ----------------------------------------------------------------------- */ 834/* ----------------------------------------------------------------------- */
@@ -607,18 +837,18 @@ static inline bool is_analog_input(struct v4l2_subdev *sd)
607{ 837{
608 struct adv7604_state *state = to_state(sd); 838 struct adv7604_state *state = to_state(sd);
609 839
610 return state->selected_input == ADV7604_INPUT_VGA_RGB || 840 return state->selected_input == ADV7604_PAD_VGA_RGB ||
611 state->selected_input == ADV7604_INPUT_VGA_COMP; 841 state->selected_input == ADV7604_PAD_VGA_COMP;
612} 842}
613 843
614static inline bool is_digital_input(struct v4l2_subdev *sd) 844static inline bool is_digital_input(struct v4l2_subdev *sd)
615{ 845{
616 struct adv7604_state *state = to_state(sd); 846 struct adv7604_state *state = to_state(sd);
617 847
618 return state->selected_input == ADV7604_INPUT_HDMI_PORT_A || 848 return state->selected_input == ADV7604_PAD_HDMI_PORT_A ||
619 state->selected_input == ADV7604_INPUT_HDMI_PORT_B || 849 state->selected_input == ADV7604_PAD_HDMI_PORT_B ||
620 state->selected_input == ADV7604_INPUT_HDMI_PORT_C || 850 state->selected_input == ADV7604_PAD_HDMI_PORT_C ||
621 state->selected_input == ADV7604_INPUT_HDMI_PORT_D; 851 state->selected_input == ADV7604_PAD_HDMI_PORT_D;
622} 852}
623 853
624/* ----------------------------------------------------------------------- */ 854/* ----------------------------------------------------------------------- */
@@ -644,119 +874,61 @@ static void adv7604_inv_register(struct v4l2_subdev *sd)
644static int adv7604_g_register(struct v4l2_subdev *sd, 874static int adv7604_g_register(struct v4l2_subdev *sd,
645 struct v4l2_dbg_register *reg) 875 struct v4l2_dbg_register *reg)
646{ 876{
647 reg->size = 1; 877 int ret;
648 switch (reg->reg >> 8) { 878
649 case 0: 879 ret = adv7604_read_reg(sd, reg->reg);
650 reg->val = io_read(sd, reg->reg & 0xff); 880 if (ret < 0) {
651 break;
652 case 1:
653 reg->val = avlink_read(sd, reg->reg & 0xff);
654 break;
655 case 2:
656 reg->val = cec_read(sd, reg->reg & 0xff);
657 break;
658 case 3:
659 reg->val = infoframe_read(sd, reg->reg & 0xff);
660 break;
661 case 4:
662 reg->val = esdp_read(sd, reg->reg & 0xff);
663 break;
664 case 5:
665 reg->val = dpp_read(sd, reg->reg & 0xff);
666 break;
667 case 6:
668 reg->val = afe_read(sd, reg->reg & 0xff);
669 break;
670 case 7:
671 reg->val = rep_read(sd, reg->reg & 0xff);
672 break;
673 case 8:
674 reg->val = edid_read(sd, reg->reg & 0xff);
675 break;
676 case 9:
677 reg->val = hdmi_read(sd, reg->reg & 0xff);
678 break;
679 case 0xa:
680 reg->val = test_read(sd, reg->reg & 0xff);
681 break;
682 case 0xb:
683 reg->val = cp_read(sd, reg->reg & 0xff);
684 break;
685 case 0xc:
686 reg->val = vdp_read(sd, reg->reg & 0xff);
687 break;
688 default:
689 v4l2_info(sd, "Register %03llx not supported\n", reg->reg); 881 v4l2_info(sd, "Register %03llx not supported\n", reg->reg);
690 adv7604_inv_register(sd); 882 adv7604_inv_register(sd);
691 break; 883 return ret;
692 } 884 }
885
886 reg->size = 1;
887 reg->val = ret;
888
693 return 0; 889 return 0;
694} 890}
695 891
696static int adv7604_s_register(struct v4l2_subdev *sd, 892static int adv7604_s_register(struct v4l2_subdev *sd,
697 const struct v4l2_dbg_register *reg) 893 const struct v4l2_dbg_register *reg)
698{ 894{
699 u8 val = reg->val & 0xff; 895 int ret;
700 896
701 switch (reg->reg >> 8) { 897 ret = adv7604_write_reg(sd, reg->reg, reg->val);
702 case 0: 898 if (ret < 0) {
703 io_write(sd, reg->reg & 0xff, val);
704 break;
705 case 1:
706 avlink_write(sd, reg->reg & 0xff, val);
707 break;
708 case 2:
709 cec_write(sd, reg->reg & 0xff, val);
710 break;
711 case 3:
712 infoframe_write(sd, reg->reg & 0xff, val);
713 break;
714 case 4:
715 esdp_write(sd, reg->reg & 0xff, val);
716 break;
717 case 5:
718 dpp_write(sd, reg->reg & 0xff, val);
719 break;
720 case 6:
721 afe_write(sd, reg->reg & 0xff, val);
722 break;
723 case 7:
724 rep_write(sd, reg->reg & 0xff, val);
725 break;
726 case 8:
727 edid_write(sd, reg->reg & 0xff, val);
728 break;
729 case 9:
730 hdmi_write(sd, reg->reg & 0xff, val);
731 break;
732 case 0xa:
733 test_write(sd, reg->reg & 0xff, val);
734 break;
735 case 0xb:
736 cp_write(sd, reg->reg & 0xff, val);
737 break;
738 case 0xc:
739 vdp_write(sd, reg->reg & 0xff, val);
740 break;
741 default:
742 v4l2_info(sd, "Register %03llx not supported\n", reg->reg); 899 v4l2_info(sd, "Register %03llx not supported\n", reg->reg);
743 adv7604_inv_register(sd); 900 adv7604_inv_register(sd);
744 break; 901 return ret;
745 } 902 }
903
746 return 0; 904 return 0;
747} 905}
748#endif 906#endif
749 907
908static unsigned int adv7604_read_cable_det(struct v4l2_subdev *sd)
909{
910 u8 value = io_read(sd, 0x6f);
911
912 return ((value & 0x10) >> 4)
913 | ((value & 0x08) >> 2)
914 | ((value & 0x04) << 0)
915 | ((value & 0x02) << 2);
916}
917
918static unsigned int adv7611_read_cable_det(struct v4l2_subdev *sd)
919{
920 u8 value = io_read(sd, 0x6f);
921
922 return value & 1;
923}
924
750static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) 925static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
751{ 926{
752 struct adv7604_state *state = to_state(sd); 927 struct adv7604_state *state = to_state(sd);
753 u8 reg_io_6f = io_read(sd, 0x6f); 928 const struct adv7604_chip_info *info = state->info;
754 929
755 return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl, 930 return v4l2_ctrl_s_ctrl(state->detect_tx_5v_ctrl,
756 ((reg_io_6f & 0x10) >> 4) | 931 info->read_cable_det(sd));
757 ((reg_io_6f & 0x08) >> 2) |
758 (reg_io_6f & 0x04) |
759 ((reg_io_6f & 0x02) << 2));
760} 932}
761 933
762static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, 934static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
@@ -787,11 +959,13 @@ static int configure_predefined_video_timings(struct v4l2_subdev *sd,
787 959
788 v4l2_dbg(1, debug, sd, "%s", __func__); 960 v4l2_dbg(1, debug, sd, "%s", __func__);
789 961
790 /* reset to default values */ 962 if (adv7604_has_afe(state)) {
791 io_write(sd, 0x16, 0x43); 963 /* reset to default values */
792 io_write(sd, 0x17, 0x5a); 964 io_write(sd, 0x16, 0x43);
965 io_write(sd, 0x17, 0x5a);
966 }
793 /* disable embedded syncs for auto graphics mode */ 967 /* disable embedded syncs for auto graphics mode */
794 cp_write_and_or(sd, 0x81, 0xef, 0x00); 968 cp_write_clr_set(sd, 0x81, 0x10, 0x00);
795 cp_write(sd, 0x8f, 0x00); 969 cp_write(sd, 0x8f, 0x00);
796 cp_write(sd, 0x90, 0x00); 970 cp_write(sd, 0x90, 0x00);
797 cp_write(sd, 0xa2, 0x00); 971 cp_write(sd, 0xa2, 0x00);
@@ -829,7 +1003,6 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
829 const struct v4l2_bt_timings *bt) 1003 const struct v4l2_bt_timings *bt)
830{ 1004{
831 struct adv7604_state *state = to_state(sd); 1005 struct adv7604_state *state = to_state(sd);
832 struct i2c_client *client = v4l2_get_subdevdata(sd);
833 u32 width = htotal(bt); 1006 u32 width = htotal(bt);
834 u32 height = vtotal(bt); 1007 u32 height = vtotal(bt);
835 u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; 1008 u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
@@ -850,12 +1023,13 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
850 io_write(sd, 0x00, 0x07); /* video std */ 1023 io_write(sd, 0x00, 0x07); /* video std */
851 io_write(sd, 0x01, 0x02); /* prim mode */ 1024 io_write(sd, 0x01, 0x02); /* prim mode */
852 /* enable embedded syncs for auto graphics mode */ 1025 /* enable embedded syncs for auto graphics mode */
853 cp_write_and_or(sd, 0x81, 0xef, 0x10); 1026 cp_write_clr_set(sd, 0x81, 0x10, 0x10);
854 1027
855 /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ 1028 /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
856 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ 1029 /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
857 /* IO-map reg. 0x16 and 0x17 should be written in sequence */ 1030 /* IO-map reg. 0x16 and 0x17 should be written in sequence */
858 if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) 1031 if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_IO,
1032 0x16, 2, pll))
859 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); 1033 v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
860 1034
861 /* active video - horizontal timing */ 1035 /* active video - horizontal timing */
@@ -906,7 +1080,8 @@ static void adv7604_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off
906 offset_buf[3] = offset_c & 0x0ff; 1080 offset_buf[3] = offset_c & 0x0ff;
907 1081
908 /* Registers must be written in this order with no i2c access in between */ 1082 /* Registers must be written in this order with no i2c access in between */
909 if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x77, 4, offset_buf)) 1083 if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP,
1084 0x77, 4, offset_buf))
910 v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__); 1085 v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
911} 1086}
912 1087
@@ -935,7 +1110,8 @@ static void adv7604_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a,
935 gain_buf[3] = ((gain_c & 0x0ff)); 1110 gain_buf[3] = ((gain_c & 0x0ff));
936 1111
937 /* Registers must be written in this order with no i2c access in between */ 1112 /* Registers must be written in this order with no i2c access in between */
938 if (adv_smbus_write_i2c_block_data(state->i2c_cp, 0x73, 4, gain_buf)) 1113 if (adv_smbus_write_i2c_block_data(state, ADV7604_PAGE_CP,
1114 0x73, 4, gain_buf))
939 v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__); 1115 v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
940} 1116}
941 1117
@@ -954,24 +1130,24 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
954 1130
955 switch (state->rgb_quantization_range) { 1131 switch (state->rgb_quantization_range) {
956 case V4L2_DV_RGB_RANGE_AUTO: 1132 case V4L2_DV_RGB_RANGE_AUTO:
957 if (state->selected_input == ADV7604_INPUT_VGA_RGB) { 1133 if (state->selected_input == ADV7604_PAD_VGA_RGB) {
958 /* Receiving analog RGB signal 1134 /* Receiving analog RGB signal
959 * Set RGB full range (0-255) */ 1135 * Set RGB full range (0-255) */
960 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1136 io_write_clr_set(sd, 0x02, 0xf0, 0x10);
961 break; 1137 break;
962 } 1138 }
963 1139
964 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1140 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
965 /* Receiving analog YPbPr signal 1141 /* Receiving analog YPbPr signal
966 * Set automode */ 1142 * Set automode */
967 io_write_and_or(sd, 0x02, 0x0f, 0xf0); 1143 io_write_clr_set(sd, 0x02, 0xf0, 0xf0);
968 break; 1144 break;
969 } 1145 }
970 1146
971 if (hdmi_signal) { 1147 if (hdmi_signal) {
972 /* Receiving HDMI signal 1148 /* Receiving HDMI signal
973 * Set automode */ 1149 * Set automode */
974 io_write_and_or(sd, 0x02, 0x0f, 0xf0); 1150 io_write_clr_set(sd, 0x02, 0xf0, 0xf0);
975 break; 1151 break;
976 } 1152 }
977 1153
@@ -980,10 +1156,10 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
980 * input format (CE/IT) in automatic mode */ 1156 * input format (CE/IT) in automatic mode */
981 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { 1157 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) {
982 /* RGB limited range (16-235) */ 1158 /* RGB limited range (16-235) */
983 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1159 io_write_clr_set(sd, 0x02, 0xf0, 0x00);
984 } else { 1160 } else {
985 /* RGB full range (0-255) */ 1161 /* RGB full range (0-255) */
986 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1162 io_write_clr_set(sd, 0x02, 0xf0, 0x10);
987 1163
988 if (is_digital_input(sd) && rgb_output) { 1164 if (is_digital_input(sd) && rgb_output) {
989 adv7604_set_offset(sd, false, 0x40, 0x40, 0x40); 1165 adv7604_set_offset(sd, false, 0x40, 0x40, 0x40);
@@ -994,25 +1170,25 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
994 } 1170 }
995 break; 1171 break;
996 case V4L2_DV_RGB_RANGE_LIMITED: 1172 case V4L2_DV_RGB_RANGE_LIMITED:
997 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1173 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
998 /* YCrCb limited range (16-235) */ 1174 /* YCrCb limited range (16-235) */
999 io_write_and_or(sd, 0x02, 0x0f, 0x20); 1175 io_write_clr_set(sd, 0x02, 0xf0, 0x20);
1000 break; 1176 break;
1001 } 1177 }
1002 1178
1003 /* RGB limited range (16-235) */ 1179 /* RGB limited range (16-235) */
1004 io_write_and_or(sd, 0x02, 0x0f, 0x00); 1180 io_write_clr_set(sd, 0x02, 0xf0, 0x00);
1005 1181
1006 break; 1182 break;
1007 case V4L2_DV_RGB_RANGE_FULL: 1183 case V4L2_DV_RGB_RANGE_FULL:
1008 if (state->selected_input == ADV7604_INPUT_VGA_COMP) { 1184 if (state->selected_input == ADV7604_PAD_VGA_COMP) {
1009 /* YCrCb full range (0-255) */ 1185 /* YCrCb full range (0-255) */
1010 io_write_and_or(sd, 0x02, 0x0f, 0x60); 1186 io_write_clr_set(sd, 0x02, 0xf0, 0x60);
1011 break; 1187 break;
1012 } 1188 }
1013 1189
1014 /* RGB full range (0-255) */ 1190 /* RGB full range (0-255) */
1015 io_write_and_or(sd, 0x02, 0x0f, 0x10); 1191 io_write_clr_set(sd, 0x02, 0xf0, 0x10);
1016 1192
1017 if (is_analog_input(sd) || hdmi_signal) 1193 if (is_analog_input(sd) || hdmi_signal)
1018 break; 1194 break;
@@ -1030,7 +1206,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
1030 1206
1031static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl) 1207static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
1032{ 1208{
1033 struct v4l2_subdev *sd = to_sd(ctrl); 1209 struct v4l2_subdev *sd =
1210 &container_of(ctrl->handler, struct adv7604_state, hdl)->sd;
1211
1034 struct adv7604_state *state = to_state(sd); 1212 struct adv7604_state *state = to_state(sd);
1035 1213
1036 switch (ctrl->id) { 1214 switch (ctrl->id) {
@@ -1051,6 +1229,8 @@ static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
1051 set_rgb_quantization_range(sd); 1229 set_rgb_quantization_range(sd);
1052 return 0; 1230 return 0;
1053 case V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE: 1231 case V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE:
1232 if (!adv7604_has_afe(state))
1233 return -EINVAL;
1054 /* Set the analog sampling phase. This is needed to find the 1234 /* Set the analog sampling phase. This is needed to find the
1055 best sampling phase for analog video: an application or 1235 best sampling phase for analog video: an application or
1056 driver has to try a number of phases and analyze the picture 1236 driver has to try a number of phases and analyze the picture
@@ -1060,7 +1240,7 @@ static int adv7604_s_ctrl(struct v4l2_ctrl *ctrl)
1060 case V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL: 1240 case V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL:
1061 /* Use the default blue color for free running mode, 1241 /* Use the default blue color for free running mode,
1062 or supply your own. */ 1242 or supply your own. */
1063 cp_write_and_or(sd, 0xbf, ~0x04, (ctrl->val << 2)); 1243 cp_write_clr_set(sd, 0xbf, 0x04, ctrl->val << 2);
1064 return 0; 1244 return 0;
1065 case V4L2_CID_ADV_RX_FREE_RUN_COLOR: 1245 case V4L2_CID_ADV_RX_FREE_RUN_COLOR:
1066 cp_write(sd, 0xc0, (ctrl->val & 0xff0000) >> 16); 1246 cp_write(sd, 0xc0, (ctrl->val & 0xff0000) >> 16);
@@ -1088,7 +1268,10 @@ static inline bool no_signal_tmds(struct v4l2_subdev *sd)
1088 1268
1089static inline bool no_lock_tmds(struct v4l2_subdev *sd) 1269static inline bool no_lock_tmds(struct v4l2_subdev *sd)
1090{ 1270{
1091 return (io_read(sd, 0x6a) & 0xe0) != 0xe0; 1271 struct adv7604_state *state = to_state(sd);
1272 const struct adv7604_chip_info *info = state->info;
1273
1274 return (io_read(sd, 0x6a) & info->tdms_lock_mask) != info->tdms_lock_mask;
1092} 1275}
1093 1276
1094static inline bool is_hdmi(struct v4l2_subdev *sd) 1277static inline bool is_hdmi(struct v4l2_subdev *sd)
@@ -1098,6 +1281,15 @@ static inline bool is_hdmi(struct v4l2_subdev *sd)
1098 1281
1099static inline bool no_lock_sspd(struct v4l2_subdev *sd) 1282static inline bool no_lock_sspd(struct v4l2_subdev *sd)
1100{ 1283{
1284 struct adv7604_state *state = to_state(sd);
1285
1286 /*
1287 * Chips without a AFE don't expose registers for the SSPD, so just assume
1288 * that we have a lock.
1289 */
1290 if (adv7604_has_afe(state))
1291 return false;
1292
1101 /* TODO channel 2 */ 1293 /* TODO channel 2 */
1102 return ((cp_read(sd, 0xb5) & 0xd0) != 0xd0); 1294 return ((cp_read(sd, 0xb5) & 0xd0) != 0xd0);
1103} 1295}
@@ -1127,6 +1319,11 @@ static inline bool no_signal(struct v4l2_subdev *sd)
1127 1319
1128static inline bool no_lock_cp(struct v4l2_subdev *sd) 1320static inline bool no_lock_cp(struct v4l2_subdev *sd)
1129{ 1321{
1322 struct adv7604_state *state = to_state(sd);
1323
1324 if (!adv7604_has_afe(state))
1325 return false;
1326
1130 /* CP has detected a non standard number of lines on the incoming 1327 /* CP has detected a non standard number of lines on the incoming
1131 video compared to what it is configured to receive by s_dv_timings */ 1328 video compared to what it is configured to receive by s_dv_timings */
1132 return io_read(sd, 0x12) & 0x01; 1329 return io_read(sd, 0x12) & 0x01;
@@ -1195,28 +1392,40 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
1195 return -1; 1392 return -1;
1196} 1393}
1197 1394
1395
1198static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi) 1396static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
1199{ 1397{
1398 struct adv7604_state *state = to_state(sd);
1399 const struct adv7604_chip_info *info = state->info;
1400 u8 polarity;
1401
1200 if (no_lock_stdi(sd) || no_lock_sspd(sd)) { 1402 if (no_lock_stdi(sd) || no_lock_sspd(sd)) {
1201 v4l2_dbg(2, debug, sd, "%s: STDI and/or SSPD not locked\n", __func__); 1403 v4l2_dbg(2, debug, sd, "%s: STDI and/or SSPD not locked\n", __func__);
1202 return -1; 1404 return -1;
1203 } 1405 }
1204 1406
1205 /* read STDI */ 1407 /* read STDI */
1206 stdi->bl = ((cp_read(sd, 0xb1) & 0x3f) << 8) | cp_read(sd, 0xb2); 1408 stdi->bl = cp_read16(sd, 0xb1, 0x3fff);
1207 stdi->lcf = ((cp_read(sd, 0xb3) & 0x7) << 8) | cp_read(sd, 0xb4); 1409 stdi->lcf = cp_read16(sd, info->lcf_reg, 0x7ff);
1208 stdi->lcvs = cp_read(sd, 0xb3) >> 3; 1410 stdi->lcvs = cp_read(sd, 0xb3) >> 3;
1209 stdi->interlaced = io_read(sd, 0x12) & 0x10; 1411 stdi->interlaced = io_read(sd, 0x12) & 0x10;
1210 1412
1211 /* read SSPD */ 1413 if (adv7604_has_afe(state)) {
1212 if ((cp_read(sd, 0xb5) & 0x03) == 0x01) { 1414 /* read SSPD */
1213 stdi->hs_pol = ((cp_read(sd, 0xb5) & 0x10) ? 1415 polarity = cp_read(sd, 0xb5);
1214 ((cp_read(sd, 0xb5) & 0x08) ? '+' : '-') : 'x'); 1416 if ((polarity & 0x03) == 0x01) {
1215 stdi->vs_pol = ((cp_read(sd, 0xb5) & 0x40) ? 1417 stdi->hs_pol = polarity & 0x10
1216 ((cp_read(sd, 0xb5) & 0x20) ? '+' : '-') : 'x'); 1418 ? (polarity & 0x08 ? '+' : '-') : 'x';
1419 stdi->vs_pol = polarity & 0x40
1420 ? (polarity & 0x20 ? '+' : '-') : 'x';
1421 } else {
1422 stdi->hs_pol = 'x';
1423 stdi->vs_pol = 'x';
1424 }
1217 } else { 1425 } else {
1218 stdi->hs_pol = 'x'; 1426 polarity = hdmi_read(sd, 0x05);
1219 stdi->vs_pol = 'x'; 1427 stdi->hs_pol = polarity & 0x20 ? '+' : '-';
1428 stdi->vs_pol = polarity & 0x10 ? '+' : '-';
1220 } 1429 }
1221 1430
1222 if (no_lock_stdi(sd) || no_lock_sspd(sd)) { 1431 if (no_lock_stdi(sd) || no_lock_sspd(sd)) {
@@ -1243,8 +1452,14 @@ static int read_stdi(struct v4l2_subdev *sd, struct stdi_readback *stdi)
1243static int adv7604_enum_dv_timings(struct v4l2_subdev *sd, 1452static int adv7604_enum_dv_timings(struct v4l2_subdev *sd,
1244 struct v4l2_enum_dv_timings *timings) 1453 struct v4l2_enum_dv_timings *timings)
1245{ 1454{
1455 struct adv7604_state *state = to_state(sd);
1456
1246 if (timings->index >= ARRAY_SIZE(adv7604_timings) - 1) 1457 if (timings->index >= ARRAY_SIZE(adv7604_timings) - 1)
1247 return -EINVAL; 1458 return -EINVAL;
1459
1460 if (timings->pad >= state->source_pad)
1461 return -EINVAL;
1462
1248 memset(timings->reserved, 0, sizeof(timings->reserved)); 1463 memset(timings->reserved, 0, sizeof(timings->reserved));
1249 timings->timings = adv7604_timings[timings->index]; 1464 timings->timings = adv7604_timings[timings->index];
1250 return 0; 1465 return 0;
@@ -1253,14 +1468,30 @@ static int adv7604_enum_dv_timings(struct v4l2_subdev *sd,
1253static int adv7604_dv_timings_cap(struct v4l2_subdev *sd, 1468static int adv7604_dv_timings_cap(struct v4l2_subdev *sd,
1254 struct v4l2_dv_timings_cap *cap) 1469 struct v4l2_dv_timings_cap *cap)
1255{ 1470{
1471 struct adv7604_state *state = to_state(sd);
1472
1473 if (cap->pad >= state->source_pad)
1474 return -EINVAL;
1475
1256 cap->type = V4L2_DV_BT_656_1120; 1476 cap->type = V4L2_DV_BT_656_1120;
1257 cap->bt.max_width = 1920; 1477 cap->bt.max_width = 1920;
1258 cap->bt.max_height = 1200; 1478 cap->bt.max_height = 1200;
1259 cap->bt.min_pixelclock = 25000000; 1479 cap->bt.min_pixelclock = 25000000;
1260 if (is_digital_input(sd)) 1480
1481 switch (cap->pad) {
1482 case ADV7604_PAD_HDMI_PORT_A:
1483 case ADV7604_PAD_HDMI_PORT_B:
1484 case ADV7604_PAD_HDMI_PORT_C:
1485 case ADV7604_PAD_HDMI_PORT_D:
1261 cap->bt.max_pixelclock = 225000000; 1486 cap->bt.max_pixelclock = 225000000;
1262 else 1487 break;
1488 case ADV7604_PAD_VGA_RGB:
1489 case ADV7604_PAD_VGA_COMP:
1490 default:
1263 cap->bt.max_pixelclock = 170000000; 1491 cap->bt.max_pixelclock = 170000000;
1492 break;
1493 }
1494
1264 cap->bt.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT | 1495 cap->bt.standards = V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
1265 V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT; 1496 V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT;
1266 cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE | 1497 cap->bt.capabilities = V4L2_DV_BT_CAP_PROGRESSIVE |
@@ -1284,10 +1515,43 @@ static void adv7604_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
1284 } 1515 }
1285} 1516}
1286 1517
1518static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
1519{
1520 unsigned int freq;
1521 int a, b;
1522
1523 a = hdmi_read(sd, 0x06);
1524 b = hdmi_read(sd, 0x3b);
1525 if (a < 0 || b < 0)
1526 return 0;
1527 freq = a * 1000000 + ((b & 0x30) >> 4) * 250000;
1528
1529 if (is_hdmi(sd)) {
1530 /* adjust for deep color mode */
1531 unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8;
1532
1533 freq = freq * 8 / bits_per_channel;
1534 }
1535
1536 return freq;
1537}
1538
1539static unsigned int adv7611_read_hdmi_pixelclock(struct v4l2_subdev *sd)
1540{
1541 int a, b;
1542
1543 a = hdmi_read(sd, 0x51);
1544 b = hdmi_read(sd, 0x52);
1545 if (a < 0 || b < 0)
1546 return 0;
1547 return ((a << 1) | (b >> 7)) * 1000000 + (b & 0x7f) * 1000000 / 128;
1548}
1549
1287static int adv7604_query_dv_timings(struct v4l2_subdev *sd, 1550static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1288 struct v4l2_dv_timings *timings) 1551 struct v4l2_dv_timings *timings)
1289{ 1552{
1290 struct adv7604_state *state = to_state(sd); 1553 struct adv7604_state *state = to_state(sd);
1554 const struct adv7604_chip_info *info = state->info;
1291 struct v4l2_bt_timings *bt = &timings->bt; 1555 struct v4l2_bt_timings *bt = &timings->bt;
1292 struct stdi_readback stdi; 1556 struct stdi_readback stdi;
1293 1557
@@ -1311,44 +1575,25 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1311 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE; 1575 V4L2_DV_INTERLACED : V4L2_DV_PROGRESSIVE;
1312 1576
1313 if (is_digital_input(sd)) { 1577 if (is_digital_input(sd)) {
1314 uint32_t freq;
1315
1316 timings->type = V4L2_DV_BT_656_1120; 1578 timings->type = V4L2_DV_BT_656_1120;
1317 1579
1318 bt->width = (hdmi_read(sd, 0x07) & 0x0f) * 256 + hdmi_read(sd, 0x08); 1580 /* FIXME: All masks are incorrect for ADV7611 */
1319 bt->height = (hdmi_read(sd, 0x09) & 0x0f) * 256 + hdmi_read(sd, 0x0a); 1581 bt->width = hdmi_read16(sd, 0x07, 0xfff);
1320 freq = (hdmi_read(sd, 0x06) * 1000000) + 1582 bt->height = hdmi_read16(sd, 0x09, 0xfff);
1321 ((hdmi_read(sd, 0x3b) & 0x30) >> 4) * 250000; 1583 bt->pixelclock = info->read_hdmi_pixelclock(sd);
1322 if (is_hdmi(sd)) { 1584 bt->hfrontporch = hdmi_read16(sd, 0x20, 0x3ff);
1323 /* adjust for deep color mode */ 1585 bt->hsync = hdmi_read16(sd, 0x22, 0x3ff);
1324 unsigned bits_per_channel = ((hdmi_read(sd, 0x0b) & 0x60) >> 4) + 8; 1586 bt->hbackporch = hdmi_read16(sd, 0x24, 0x3ff);
1325 1587 bt->vfrontporch = hdmi_read16(sd, 0x2a, 0x1fff) / 2;
1326 freq = freq * 8 / bits_per_channel; 1588 bt->vsync = hdmi_read16(sd, 0x2e, 0x1fff) / 2;
1327 } 1589 bt->vbackporch = hdmi_read16(sd, 0x32, 0x1fff) / 2;
1328 bt->pixelclock = freq;
1329 bt->hfrontporch = (hdmi_read(sd, 0x20) & 0x03) * 256 +
1330 hdmi_read(sd, 0x21);
1331 bt->hsync = (hdmi_read(sd, 0x22) & 0x03) * 256 +
1332 hdmi_read(sd, 0x23);
1333 bt->hbackporch = (hdmi_read(sd, 0x24) & 0x03) * 256 +
1334 hdmi_read(sd, 0x25);
1335 bt->vfrontporch = ((hdmi_read(sd, 0x2a) & 0x1f) * 256 +
1336 hdmi_read(sd, 0x2b)) / 2;
1337 bt->vsync = ((hdmi_read(sd, 0x2e) & 0x1f) * 256 +
1338 hdmi_read(sd, 0x2f)) / 2;
1339 bt->vbackporch = ((hdmi_read(sd, 0x32) & 0x1f) * 256 +
1340 hdmi_read(sd, 0x33)) / 2;
1341 bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) | 1590 bt->polarities = ((hdmi_read(sd, 0x05) & 0x10) ? V4L2_DV_VSYNC_POS_POL : 0) |
1342 ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0); 1591 ((hdmi_read(sd, 0x05) & 0x20) ? V4L2_DV_HSYNC_POS_POL : 0);
1343 if (bt->interlaced == V4L2_DV_INTERLACED) { 1592 if (bt->interlaced == V4L2_DV_INTERLACED) {
1344 bt->height += (hdmi_read(sd, 0x0b) & 0x0f) * 256 + 1593 bt->height += hdmi_read16(sd, 0x0b, 0xfff);
1345 hdmi_read(sd, 0x0c); 1594 bt->il_vfrontporch = hdmi_read16(sd, 0x2c, 0x1fff) / 2;
1346 bt->il_vfrontporch = ((hdmi_read(sd, 0x2c) & 0x1f) * 256 + 1595 bt->il_vsync = hdmi_read16(sd, 0x30, 0x1fff) / 2;
1347 hdmi_read(sd, 0x2d)) / 2; 1596 bt->vbackporch = hdmi_read16(sd, 0x34, 0x1fff) / 2;
1348 bt->il_vsync = ((hdmi_read(sd, 0x30) & 0x1f) * 256 +
1349 hdmi_read(sd, 0x31)) / 2;
1350 bt->vbackporch = ((hdmi_read(sd, 0x34) & 0x1f) * 256 +
1351 hdmi_read(sd, 0x35)) / 2;
1352 } 1597 }
1353 adv7604_fill_optional_dv_timings_fields(sd, timings); 1598 adv7604_fill_optional_dv_timings_fields(sd, timings);
1354 } else { 1599 } else {
@@ -1378,11 +1623,11 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
1378 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__); 1623 v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
1379 /* TODO restart STDI for Sync Channel 2 */ 1624 /* TODO restart STDI for Sync Channel 2 */
1380 /* enter one-shot mode */ 1625 /* enter one-shot mode */
1381 cp_write_and_or(sd, 0x86, 0xf9, 0x00); 1626 cp_write_clr_set(sd, 0x86, 0x06, 0x00);
1382 /* trigger STDI restart */ 1627 /* trigger STDI restart */
1383 cp_write_and_or(sd, 0x86, 0xf9, 0x04); 1628 cp_write_clr_set(sd, 0x86, 0x06, 0x04);
1384 /* reset to continuous mode */ 1629 /* reset to continuous mode */
1385 cp_write_and_or(sd, 0x86, 0xf9, 0x02); 1630 cp_write_clr_set(sd, 0x86, 0x06, 0x02);
1386 state->restart_stdi_once = false; 1631 state->restart_stdi_once = false;
1387 return -ENOLINK; 1632 return -ENOLINK;
1388 } 1633 }
@@ -1441,7 +1686,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
1441 1686
1442 state->timings = *timings; 1687 state->timings = *timings;
1443 1688
1444 cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); 1689 cp_write_clr_set(sd, 0x91, 0x40, bt->interlaced ? 0x40 : 0x00);
1445 1690
1446 /* Use prim_mode and vid_std when available */ 1691 /* Use prim_mode and vid_std when available */
1447 err = configure_predefined_video_timings(sd, timings); 1692 err = configure_predefined_video_timings(sd, timings);
@@ -1468,6 +1713,16 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
1468 return 0; 1713 return 0;
1469} 1714}
1470 1715
1716static void adv7604_set_termination(struct v4l2_subdev *sd, bool enable)
1717{
1718 hdmi_write(sd, 0x01, enable ? 0x00 : 0x78);
1719}
1720
1721static void adv7611_set_termination(struct v4l2_subdev *sd, bool enable)
1722{
1723 hdmi_write(sd, 0x83, enable ? 0xfe : 0xff);
1724}
1725
1471static void enable_input(struct v4l2_subdev *sd) 1726static void enable_input(struct v4l2_subdev *sd)
1472{ 1727{
1473 struct adv7604_state *state = to_state(sd); 1728 struct adv7604_state *state = to_state(sd);
@@ -1475,10 +1730,10 @@ static void enable_input(struct v4l2_subdev *sd)
1475 if (is_analog_input(sd)) { 1730 if (is_analog_input(sd)) {
1476 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ 1731 io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
1477 } else if (is_digital_input(sd)) { 1732 } else if (is_digital_input(sd)) {
1478 hdmi_write_and_or(sd, 0x00, 0xfc, state->selected_input); 1733 hdmi_write_clr_set(sd, 0x00, 0x03, state->selected_input);
1479 hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ 1734 state->info->set_termination(sd, true);
1480 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ 1735 io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
1481 hdmi_write_and_or(sd, 0x1a, 0xef, 0x00); /* Unmute audio */ 1736 hdmi_write_clr_set(sd, 0x1a, 0x10, 0x00); /* Unmute audio */
1482 } else { 1737 } else {
1483 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n", 1738 v4l2_dbg(2, debug, sd, "%s: Unknown port %d selected\n",
1484 __func__, state->selected_input); 1739 __func__, state->selected_input);
@@ -1487,67 +1742,36 @@ static void enable_input(struct v4l2_subdev *sd)
1487 1742
1488static void disable_input(struct v4l2_subdev *sd) 1743static void disable_input(struct v4l2_subdev *sd)
1489{ 1744{
1490 hdmi_write_and_or(sd, 0x1a, 0xef, 0x10); /* Mute audio */ 1745 struct adv7604_state *state = to_state(sd);
1746
1747 hdmi_write_clr_set(sd, 0x1a, 0x10, 0x10); /* Mute audio */
1491 msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 7.16.10] */ 1748 msleep(16); /* 512 samples with >= 32 kHz sample rate [REF_03, c. 7.16.10] */
1492 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */ 1749 io_write(sd, 0x15, 0xbe); /* Tristate all outputs from video core */
1493 hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ 1750 state->info->set_termination(sd, false);
1494} 1751}
1495 1752
1496static void select_input(struct v4l2_subdev *sd) 1753static void select_input(struct v4l2_subdev *sd)
1497{ 1754{
1498 struct adv7604_state *state = to_state(sd); 1755 struct adv7604_state *state = to_state(sd);
1756 const struct adv7604_chip_info *info = state->info;
1499 1757
1500 if (is_analog_input(sd)) { 1758 if (is_analog_input(sd)) {
1501 /* reset ADI recommended settings for HDMI: */ 1759 adv7604_write_reg_seq(sd, info->recommended_settings[0]);
1502 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
1503 hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
1504 hdmi_write(sd, 0x3d, 0x00); /* DDC bus active pull-up control */
1505 hdmi_write(sd, 0x3e, 0x74); /* TMDS PLL optimization */
1506 hdmi_write(sd, 0x4e, 0x3b); /* TMDS PLL optimization */
1507 hdmi_write(sd, 0x57, 0x74); /* TMDS PLL optimization */
1508 hdmi_write(sd, 0x58, 0x63); /* TMDS PLL optimization */
1509 hdmi_write(sd, 0x8d, 0x18); /* equaliser */
1510 hdmi_write(sd, 0x8e, 0x34); /* equaliser */
1511 hdmi_write(sd, 0x93, 0x88); /* equaliser */
1512 hdmi_write(sd, 0x94, 0x2e); /* equaliser */
1513 hdmi_write(sd, 0x96, 0x00); /* enable automatic EQ changing */
1514 1760
1515 afe_write(sd, 0x00, 0x08); /* power up ADC */ 1761 afe_write(sd, 0x00, 0x08); /* power up ADC */
1516 afe_write(sd, 0x01, 0x06); /* power up Analog Front End */ 1762 afe_write(sd, 0x01, 0x06); /* power up Analog Front End */
1517 afe_write(sd, 0xc8, 0x00); /* phase control */ 1763 afe_write(sd, 0xc8, 0x00); /* phase control */
1518
1519 /* set ADI recommended settings for digitizer */
1520 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
1521 afe_write(sd, 0x12, 0x7b); /* ADC noise shaping filter controls */
1522 afe_write(sd, 0x0c, 0x1f); /* CP core gain controls */
1523 cp_write(sd, 0x3e, 0x04); /* CP core pre-gain control */
1524 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
1525 cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
1526 } else if (is_digital_input(sd)) { 1764 } else if (is_digital_input(sd)) {
1527 hdmi_write(sd, 0x00, state->selected_input & 0x03); 1765 hdmi_write(sd, 0x00, state->selected_input & 0x03);
1528 1766
1529 /* set ADI recommended settings for HDMI: */ 1767 adv7604_write_reg_seq(sd, info->recommended_settings[1]);
1530 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ 1768
1531 hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ 1769 if (adv7604_has_afe(state)) {
1532 hdmi_write(sd, 0x3d, 0x10); /* DDC bus active pull-up control */ 1770 afe_write(sd, 0x00, 0xff); /* power down ADC */
1533 hdmi_write(sd, 0x3e, 0x39); /* TMDS PLL optimization */ 1771 afe_write(sd, 0x01, 0xfe); /* power down Analog Front End */
1534 hdmi_write(sd, 0x4e, 0x3b); /* TMDS PLL optimization */ 1772 afe_write(sd, 0xc8, 0x40); /* phase control */
1535 hdmi_write(sd, 0x57, 0xb6); /* TMDS PLL optimization */ 1773 }
1536 hdmi_write(sd, 0x58, 0x03); /* TMDS PLL optimization */ 1774
1537 hdmi_write(sd, 0x8d, 0x18); /* equaliser */
1538 hdmi_write(sd, 0x8e, 0x34); /* equaliser */
1539 hdmi_write(sd, 0x93, 0x8b); /* equaliser */
1540 hdmi_write(sd, 0x94, 0x2d); /* equaliser */
1541 hdmi_write(sd, 0x96, 0x01); /* enable automatic EQ changing */
1542
1543 afe_write(sd, 0x00, 0xff); /* power down ADC */
1544 afe_write(sd, 0x01, 0xfe); /* power down Analog Front End */
1545 afe_write(sd, 0xc8, 0x40); /* phase control */
1546
1547 /* reset ADI recommended settings for digitizer */
1548 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
1549 afe_write(sd, 0x12, 0xfb); /* ADC noise shaping filter controls */
1550 afe_write(sd, 0x0c, 0x0d); /* CP core gain controls */
1551 cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */ 1775 cp_write(sd, 0x3e, 0x00); /* CP core pre-gain control */
1552 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */ 1776 cp_write(sd, 0xc3, 0x39); /* CP coast control. Graphics mode */
1553 cp_write(sd, 0x40, 0x80); /* CP core pre-gain control. Graphics mode */ 1777 cp_write(sd, 0x40, 0x80); /* CP core pre-gain control. Graphics mode */
@@ -1568,6 +1792,9 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
1568 if (input == state->selected_input) 1792 if (input == state->selected_input)
1569 return 0; 1793 return 0;
1570 1794
1795 if (input > state->info->max_port)
1796 return -EINVAL;
1797
1571 state->selected_input = input; 1798 state->selected_input = input;
1572 1799
1573 disable_input(sd); 1800 disable_input(sd);
@@ -1579,34 +1806,139 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
1579 return 0; 1806 return 0;
1580} 1807}
1581 1808
1582static int adv7604_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index, 1809static int adv7604_enum_mbus_code(struct v4l2_subdev *sd,
1583 enum v4l2_mbus_pixelcode *code) 1810 struct v4l2_subdev_fh *fh,
1811 struct v4l2_subdev_mbus_code_enum *code)
1812{
1813 struct adv7604_state *state = to_state(sd);
1814
1815 if (code->index >= state->info->nformats)
1816 return -EINVAL;
1817
1818 code->code = state->info->formats[code->index].code;
1819
1820 return 0;
1821}
1822
1823static void adv7604_fill_format(struct adv7604_state *state,
1824 struct v4l2_mbus_framefmt *format)
1825{
1826 memset(format, 0, sizeof(*format));
1827
1828 format->width = state->timings.bt.width;
1829 format->height = state->timings.bt.height;
1830 format->field = V4L2_FIELD_NONE;
1831
1832 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861)
1833 format->colorspace = (state->timings.bt.height <= 576) ?
1834 V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709;
1835}
1836
1837/*
1838 * Compute the op_ch_sel value required to obtain on the bus the component order
1839 * corresponding to the selected format taking into account bus reordering
1840 * applied by the board at the output of the device.
1841 *
1842 * The following table gives the op_ch_value from the format component order
1843 * (expressed as op_ch_sel value in column) and the bus reordering (expressed as
1844 * adv7604_bus_order value in row).
1845 *
1846 * | GBR(0) GRB(1) BGR(2) RGB(3) BRG(4) RBG(5)
1847 * ----------+-------------------------------------------------
1848 * RGB (NOP) | GBR GRB BGR RGB BRG RBG
1849 * GRB (1-2) | BGR RGB GBR GRB RBG BRG
1850 * RBG (2-3) | GRB GBR BRG RBG BGR RGB
1851 * BGR (1-3) | RBG BRG RGB BGR GRB GBR
1852 * BRG (ROR) | BRG RBG GRB GBR RGB BGR
1853 * GBR (ROL) | RGB BGR RBG BRG GBR GRB
1854 */
1855static unsigned int adv7604_op_ch_sel(struct adv7604_state *state)
1856{
1857#define _SEL(a,b,c,d,e,f) { \
1858 ADV7604_OP_CH_SEL_##a, ADV7604_OP_CH_SEL_##b, ADV7604_OP_CH_SEL_##c, \
1859 ADV7604_OP_CH_SEL_##d, ADV7604_OP_CH_SEL_##e, ADV7604_OP_CH_SEL_##f }
1860#define _BUS(x) [ADV7604_BUS_ORDER_##x]
1861
1862 static const unsigned int op_ch_sel[6][6] = {
1863 _BUS(RGB) /* NOP */ = _SEL(GBR, GRB, BGR, RGB, BRG, RBG),
1864 _BUS(GRB) /* 1-2 */ = _SEL(BGR, RGB, GBR, GRB, RBG, BRG),
1865 _BUS(RBG) /* 2-3 */ = _SEL(GRB, GBR, BRG, RBG, BGR, RGB),
1866 _BUS(BGR) /* 1-3 */ = _SEL(RBG, BRG, RGB, BGR, GRB, GBR),
1867 _BUS(BRG) /* ROR */ = _SEL(BRG, RBG, GRB, GBR, RGB, BGR),
1868 _BUS(GBR) /* ROL */ = _SEL(RGB, BGR, RBG, BRG, GBR, GRB),
1869 };
1870
1871 return op_ch_sel[state->pdata.bus_order][state->format->op_ch_sel >> 5];
1872}
1873
1874static void adv7604_setup_format(struct adv7604_state *state)
1875{
1876 struct v4l2_subdev *sd = &state->sd;
1877
1878 io_write_clr_set(sd, 0x02, 0x02,
1879 state->format->rgb_out ? ADV7604_RGB_OUT : 0);
1880 io_write(sd, 0x03, state->format->op_format_sel |
1881 state->pdata.op_format_mode_sel);
1882 io_write_clr_set(sd, 0x04, 0xe0, adv7604_op_ch_sel(state));
1883 io_write_clr_set(sd, 0x05, 0x01,
1884 state->format->swap_cb_cr ? ADV7604_OP_SWAP_CB_CR : 0);
1885}
1886
1887static int adv7604_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1888 struct v4l2_subdev_format *format)
1584{ 1889{
1585 if (index) 1890 struct adv7604_state *state = to_state(sd);
1891
1892 if (format->pad != state->source_pad)
1586 return -EINVAL; 1893 return -EINVAL;
1587 /* Good enough for now */ 1894
1588 *code = V4L2_MBUS_FMT_FIXED; 1895 adv7604_fill_format(state, &format->format);
1896
1897 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
1898 struct v4l2_mbus_framefmt *fmt;
1899
1900 fmt = v4l2_subdev_get_try_format(fh, format->pad);
1901 format->format.code = fmt->code;
1902 } else {
1903 format->format.code = state->format->code;
1904 }
1905
1589 return 0; 1906 return 0;
1590} 1907}
1591 1908
1592static int adv7604_g_mbus_fmt(struct v4l2_subdev *sd, 1909static int adv7604_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1593 struct v4l2_mbus_framefmt *fmt) 1910 struct v4l2_subdev_format *format)
1594{ 1911{
1595 struct adv7604_state *state = to_state(sd); 1912 struct adv7604_state *state = to_state(sd);
1913 const struct adv7604_format_info *info;
1596 1914
1597 fmt->width = state->timings.bt.width; 1915 if (format->pad != state->source_pad)
1598 fmt->height = state->timings.bt.height; 1916 return -EINVAL;
1599 fmt->code = V4L2_MBUS_FMT_FIXED; 1917
1600 fmt->field = V4L2_FIELD_NONE; 1918 info = adv7604_format_info(state, format->format.code);
1601 if (state->timings.bt.standards & V4L2_DV_BT_STD_CEA861) { 1919 if (info == NULL)
1602 fmt->colorspace = (state->timings.bt.height <= 576) ? 1920 info = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8);
1603 V4L2_COLORSPACE_SMPTE170M : V4L2_COLORSPACE_REC709; 1921
1922 adv7604_fill_format(state, &format->format);
1923 format->format.code = info->code;
1924
1925 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
1926 struct v4l2_mbus_framefmt *fmt;
1927
1928 fmt = v4l2_subdev_get_try_format(fh, format->pad);
1929 fmt->code = format->format.code;
1930 } else {
1931 state->format = info;
1932 adv7604_setup_format(state);
1604 } 1933 }
1934
1605 return 0; 1935 return 0;
1606} 1936}
1607 1937
1608static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled) 1938static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1609{ 1939{
1940 struct adv7604_state *state = to_state(sd);
1941 const struct adv7604_chip_info *info = state->info;
1610 const u8 irq_reg_0x43 = io_read(sd, 0x43); 1942 const u8 irq_reg_0x43 = io_read(sd, 0x43);
1611 const u8 irq_reg_0x6b = io_read(sd, 0x6b); 1943 const u8 irq_reg_0x6b = io_read(sd, 0x6b);
1612 const u8 irq_reg_0x70 = io_read(sd, 0x70); 1944 const u8 irq_reg_0x70 = io_read(sd, 0x70);
@@ -1625,7 +1957,9 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1625 1957
1626 /* format change */ 1958 /* format change */
1627 fmt_change = irq_reg_0x43 & 0x98; 1959 fmt_change = irq_reg_0x43 & 0x98;
1628 fmt_change_digital = is_digital_input(sd) ? (irq_reg_0x6b & 0xc0) : 0; 1960 fmt_change_digital = is_digital_input(sd)
1961 ? irq_reg_0x6b & info->fmt_change_digital_mask
1962 : 0;
1629 1963
1630 if (fmt_change || fmt_change_digital) { 1964 if (fmt_change || fmt_change_digital) {
1631 v4l2_dbg(1, debug, sd, 1965 v4l2_dbg(1, debug, sd,
@@ -1647,7 +1981,7 @@ static int adv7604_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
1647 } 1981 }
1648 1982
1649 /* tx 5v detect */ 1983 /* tx 5v detect */
1650 tx_5v = io_read(sd, 0x70) & 0x1e; 1984 tx_5v = io_read(sd, 0x70) & info->cable_det_mask;
1651 if (tx_5v) { 1985 if (tx_5v) {
1652 v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v); 1986 v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v);
1653 io_write(sd, 0x71, tx_5v); 1987 io_write(sd, 0x71, tx_5v);
@@ -1663,7 +1997,7 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1663 struct adv7604_state *state = to_state(sd); 1997 struct adv7604_state *state = to_state(sd);
1664 u8 *data = NULL; 1998 u8 *data = NULL;
1665 1999
1666 if (edid->pad > ADV7604_EDID_PORT_D) 2000 if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
1667 return -EINVAL; 2001 return -EINVAL;
1668 if (edid->blocks == 0) 2002 if (edid->blocks == 0)
1669 return -EINVAL; 2003 return -EINVAL;
@@ -1678,10 +2012,10 @@ static int adv7604_get_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1678 edid->blocks = state->edid.blocks; 2012 edid->blocks = state->edid.blocks;
1679 2013
1680 switch (edid->pad) { 2014 switch (edid->pad) {
1681 case ADV7604_EDID_PORT_A: 2015 case ADV7604_PAD_HDMI_PORT_A:
1682 case ADV7604_EDID_PORT_B: 2016 case ADV7604_PAD_HDMI_PORT_B:
1683 case ADV7604_EDID_PORT_C: 2017 case ADV7604_PAD_HDMI_PORT_C:
1684 case ADV7604_EDID_PORT_D: 2018 case ADV7604_PAD_HDMI_PORT_D:
1685 if (state->edid.present & (1 << edid->pad)) 2019 if (state->edid.present & (1 << edid->pad))
1686 data = state->edid.edid; 2020 data = state->edid.edid;
1687 break; 2021 break;
@@ -1729,20 +2063,20 @@ static int get_edid_spa_location(const u8 *edid)
1729static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid) 2063static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1730{ 2064{
1731 struct adv7604_state *state = to_state(sd); 2065 struct adv7604_state *state = to_state(sd);
2066 const struct adv7604_chip_info *info = state->info;
1732 int spa_loc; 2067 int spa_loc;
1733 int tmp = 0;
1734 int err; 2068 int err;
1735 int i; 2069 int i;
1736 2070
1737 if (edid->pad > ADV7604_EDID_PORT_D) 2071 if (edid->pad > ADV7604_PAD_HDMI_PORT_D)
1738 return -EINVAL; 2072 return -EINVAL;
1739 if (edid->start_block != 0) 2073 if (edid->start_block != 0)
1740 return -EINVAL; 2074 return -EINVAL;
1741 if (edid->blocks == 0) { 2075 if (edid->blocks == 0) {
1742 /* Disable hotplug and I2C access to EDID RAM from DDC port */ 2076 /* Disable hotplug and I2C access to EDID RAM from DDC port */
1743 state->edid.present &= ~(1 << edid->pad); 2077 state->edid.present &= ~(1 << edid->pad);
1744 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&state->edid.present); 2078 adv7604_set_hpd(state, state->edid.present);
1745 rep_write_and_or(sd, 0x77, 0xf0, state->edid.present); 2079 rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present);
1746 2080
1747 /* Fall back to a 16:9 aspect ratio */ 2081 /* Fall back to a 16:9 aspect ratio */
1748 state->aspect_ratio.numerator = 16; 2082 state->aspect_ratio.numerator = 16;
@@ -1765,35 +2099,41 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1765 2099
1766 /* Disable hotplug and I2C access to EDID RAM from DDC port */ 2100 /* Disable hotplug and I2C access to EDID RAM from DDC port */
1767 cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); 2101 cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
1768 v4l2_subdev_notify(sd, ADV7604_HOTPLUG, (void *)&tmp); 2102 adv7604_set_hpd(state, 0);
1769 rep_write_and_or(sd, 0x77, 0xf0, 0x00); 2103 rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, 0x00);
1770 2104
1771 spa_loc = get_edid_spa_location(edid->edid); 2105 spa_loc = get_edid_spa_location(edid->edid);
1772 if (spa_loc < 0) 2106 if (spa_loc < 0)
1773 spa_loc = 0xc0; /* Default value [REF_02, p. 116] */ 2107 spa_loc = 0xc0; /* Default value [REF_02, p. 116] */
1774 2108
1775 switch (edid->pad) { 2109 switch (edid->pad) {
1776 case ADV7604_EDID_PORT_A: 2110 case ADV7604_PAD_HDMI_PORT_A:
1777 state->spa_port_a[0] = edid->edid[spa_loc]; 2111 state->spa_port_a[0] = edid->edid[spa_loc];
1778 state->spa_port_a[1] = edid->edid[spa_loc + 1]; 2112 state->spa_port_a[1] = edid->edid[spa_loc + 1];
1779 break; 2113 break;
1780 case ADV7604_EDID_PORT_B: 2114 case ADV7604_PAD_HDMI_PORT_B:
1781 rep_write(sd, 0x70, edid->edid[spa_loc]); 2115 rep_write(sd, 0x70, edid->edid[spa_loc]);
1782 rep_write(sd, 0x71, edid->edid[spa_loc + 1]); 2116 rep_write(sd, 0x71, edid->edid[spa_loc + 1]);
1783 break; 2117 break;
1784 case ADV7604_EDID_PORT_C: 2118 case ADV7604_PAD_HDMI_PORT_C:
1785 rep_write(sd, 0x72, edid->edid[spa_loc]); 2119 rep_write(sd, 0x72, edid->edid[spa_loc]);
1786 rep_write(sd, 0x73, edid->edid[spa_loc + 1]); 2120 rep_write(sd, 0x73, edid->edid[spa_loc + 1]);
1787 break; 2121 break;
1788 case ADV7604_EDID_PORT_D: 2122 case ADV7604_PAD_HDMI_PORT_D:
1789 rep_write(sd, 0x74, edid->edid[spa_loc]); 2123 rep_write(sd, 0x74, edid->edid[spa_loc]);
1790 rep_write(sd, 0x75, edid->edid[spa_loc + 1]); 2124 rep_write(sd, 0x75, edid->edid[spa_loc + 1]);
1791 break; 2125 break;
1792 default: 2126 default:
1793 return -EINVAL; 2127 return -EINVAL;
1794 } 2128 }
1795 rep_write(sd, 0x76, spa_loc & 0xff); 2129
1796 rep_write_and_or(sd, 0x77, 0xbf, (spa_loc >> 2) & 0x40); 2130 if (info->type == ADV7604) {
2131 rep_write(sd, 0x76, spa_loc & 0xff);
2132 rep_write_clr_set(sd, 0x77, 0x40, (spa_loc & 0x100) >> 2);
2133 } else {
2134 /* FIXME: Where is the SPA location LSB register ? */
2135 rep_write_clr_set(sd, 0x71, 0x01, (spa_loc & 0x100) >> 8);
2136 }
1797 2137
1798 edid->edid[spa_loc] = state->spa_port_a[0]; 2138 edid->edid[spa_loc] = state->spa_port_a[0];
1799 edid->edid[spa_loc + 1] = state->spa_port_a[1]; 2139 edid->edid[spa_loc + 1] = state->spa_port_a[1];
@@ -1812,10 +2152,10 @@ static int adv7604_set_edid(struct v4l2_subdev *sd, struct v4l2_edid *edid)
1812 2152
1813 /* adv7604 calculates the checksums and enables I2C access to internal 2153 /* adv7604 calculates the checksums and enables I2C access to internal
1814 EDID RAM from DDC port. */ 2154 EDID RAM from DDC port. */
1815 rep_write_and_or(sd, 0x77, 0xf0, state->edid.present); 2155 rep_write_clr_set(sd, info->edid_enable_reg, 0x0f, state->edid.present);
1816 2156
1817 for (i = 0; i < 1000; i++) { 2157 for (i = 0; i < 1000; i++) {
1818 if (rep_read(sd, 0x7d) & state->edid.present) 2158 if (rep_read(sd, info->edid_status_reg) & state->edid.present)
1819 break; 2159 break;
1820 mdelay(1); 2160 mdelay(1);
1821 } 2161 }
@@ -1878,17 +2218,20 @@ static void print_avi_infoframe(struct v4l2_subdev *sd)
1878static int adv7604_log_status(struct v4l2_subdev *sd) 2218static int adv7604_log_status(struct v4l2_subdev *sd)
1879{ 2219{
1880 struct adv7604_state *state = to_state(sd); 2220 struct adv7604_state *state = to_state(sd);
2221 const struct adv7604_chip_info *info = state->info;
1881 struct v4l2_dv_timings timings; 2222 struct v4l2_dv_timings timings;
1882 struct stdi_readback stdi; 2223 struct stdi_readback stdi;
1883 u8 reg_io_0x02 = io_read(sd, 0x02); 2224 u8 reg_io_0x02 = io_read(sd, 0x02);
2225 u8 edid_enabled;
2226 u8 cable_det;
1884 2227
1885 char *csc_coeff_sel_rb[16] = { 2228 static const char * const csc_coeff_sel_rb[16] = {
1886 "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB", 2229 "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB",
1887 "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709", 2230 "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709",
1888 "reserved", "YPbPr709 -> YPbPr601", "YPbPr601 -> YPbPr709", 2231 "reserved", "YPbPr709 -> YPbPr601", "YPbPr601 -> YPbPr709",
1889 "reserved", "reserved", "reserved", "reserved", "manual" 2232 "reserved", "reserved", "reserved", "reserved", "manual"
1890 }; 2233 };
1891 char *input_color_space_txt[16] = { 2234 static const char * const input_color_space_txt[16] = {
1892 "RGB limited range (16-235)", "RGB full range (0-255)", 2235 "RGB limited range (16-235)", "RGB full range (0-255)",
1893 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)", 2236 "YCbCr Bt.601 (16-235)", "YCbCr Bt.709 (16-235)",
1894 "xvYCC Bt.601", "xvYCC Bt.709", 2237 "xvYCC Bt.601", "xvYCC Bt.709",
@@ -1896,12 +2239,12 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1896 "invalid", "invalid", "invalid", "invalid", "invalid", 2239 "invalid", "invalid", "invalid", "invalid", "invalid",
1897 "invalid", "invalid", "automatic" 2240 "invalid", "invalid", "automatic"
1898 }; 2241 };
1899 char *rgb_quantization_range_txt[] = { 2242 static const char * const rgb_quantization_range_txt[] = {
1900 "Automatic", 2243 "Automatic",
1901 "RGB limited range (16-235)", 2244 "RGB limited range (16-235)",
1902 "RGB full range (0-255)", 2245 "RGB full range (0-255)",
1903 }; 2246 };
1904 char *deep_color_mode_txt[4] = { 2247 static const char * const deep_color_mode_txt[4] = {
1905 "8-bits per channel", 2248 "8-bits per channel",
1906 "10-bits per channel", 2249 "10-bits per channel",
1907 "12-bits per channel", 2250 "12-bits per channel",
@@ -1910,20 +2253,22 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
1910 2253
1911 v4l2_info(sd, "-----Chip status-----\n"); 2254 v4l2_info(sd, "-----Chip status-----\n");
1912 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on"); 2255 v4l2_info(sd, "Chip power: %s\n", no_power(sd) ? "off" : "on");
2256 edid_enabled = rep_read(sd, info->edid_status_reg);
1913 v4l2_info(sd, "EDID enabled port A: %s, B: %s, C: %s, D: %s\n", 2257 v4l2_info(sd, "EDID enabled port A: %s, B: %s, C: %s, D: %s\n",
1914 ((rep_read(sd, 0x7d) & 0x01) ? "Yes" : "No"), 2258 ((edid_enabled & 0x01) ? "Yes" : "No"),
1915 ((rep_read(sd, 0x7d) & 0x02) ? "Yes" : "No"), 2259 ((edid_enabled & 0x02) ? "Yes" : "No"),
1916 ((rep_read(sd, 0x7d) & 0x04) ? "Yes" : "No"), 2260 ((edid_enabled & 0x04) ? "Yes" : "No"),
1917 ((rep_read(sd, 0x7d) & 0x08) ? "Yes" : "No")); 2261 ((edid_enabled & 0x08) ? "Yes" : "No"));
1918 v4l2_info(sd, "CEC: %s\n", !!(cec_read(sd, 0x2a) & 0x01) ? 2262 v4l2_info(sd, "CEC: %s\n", !!(cec_read(sd, 0x2a) & 0x01) ?
1919 "enabled" : "disabled"); 2263 "enabled" : "disabled");
1920 2264
1921 v4l2_info(sd, "-----Signal status-----\n"); 2265 v4l2_info(sd, "-----Signal status-----\n");
2266 cable_det = info->read_cable_det(sd);
1922 v4l2_info(sd, "Cable detected (+5V power) port A: %s, B: %s, C: %s, D: %s\n", 2267 v4l2_info(sd, "Cable detected (+5V power) port A: %s, B: %s, C: %s, D: %s\n",
1923 ((io_read(sd, 0x6f) & 0x10) ? "Yes" : "No"), 2268 ((cable_det & 0x01) ? "Yes" : "No"),
1924 ((io_read(sd, 0x6f) & 0x08) ? "Yes" : "No"), 2269 ((cable_det & 0x02) ? "Yes" : "No"),
1925 ((io_read(sd, 0x6f) & 0x04) ? "Yes" : "No"), 2270 ((cable_det & 0x04) ? "Yes" : "No"),
1926 ((io_read(sd, 0x6f) & 0x02) ? "Yes" : "No")); 2271 ((cable_det & 0x08) ? "Yes" : "No"));
1927 v4l2_info(sd, "TMDS signal detected: %s\n", 2272 v4l2_info(sd, "TMDS signal detected: %s\n",
1928 no_signal_tmds(sd) ? "false" : "true"); 2273 no_signal_tmds(sd) ? "false" : "true");
1929 v4l2_info(sd, "TMDS signal locked: %s\n", 2274 v4l2_info(sd, "TMDS signal locked: %s\n",
@@ -2017,13 +2362,6 @@ static const struct v4l2_ctrl_ops adv7604_ctrl_ops = {
2017 2362
2018static const struct v4l2_subdev_core_ops adv7604_core_ops = { 2363static const struct v4l2_subdev_core_ops adv7604_core_ops = {
2019 .log_status = adv7604_log_status, 2364 .log_status = adv7604_log_status,
2020 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
2021 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
2022 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
2023 .g_ctrl = v4l2_subdev_g_ctrl,
2024 .s_ctrl = v4l2_subdev_s_ctrl,
2025 .queryctrl = v4l2_subdev_queryctrl,
2026 .querymenu = v4l2_subdev_querymenu,
2027 .interrupt_service_routine = adv7604_isr, 2365 .interrupt_service_routine = adv7604_isr,
2028#ifdef CONFIG_VIDEO_ADV_DEBUG 2366#ifdef CONFIG_VIDEO_ADV_DEBUG
2029 .g_register = adv7604_g_register, 2367 .g_register = adv7604_g_register,
@@ -2037,17 +2375,16 @@ static const struct v4l2_subdev_video_ops adv7604_video_ops = {
2037 .s_dv_timings = adv7604_s_dv_timings, 2375 .s_dv_timings = adv7604_s_dv_timings,
2038 .g_dv_timings = adv7604_g_dv_timings, 2376 .g_dv_timings = adv7604_g_dv_timings,
2039 .query_dv_timings = adv7604_query_dv_timings, 2377 .query_dv_timings = adv7604_query_dv_timings,
2040 .enum_dv_timings = adv7604_enum_dv_timings,
2041 .dv_timings_cap = adv7604_dv_timings_cap,
2042 .enum_mbus_fmt = adv7604_enum_mbus_fmt,
2043 .g_mbus_fmt = adv7604_g_mbus_fmt,
2044 .try_mbus_fmt = adv7604_g_mbus_fmt,
2045 .s_mbus_fmt = adv7604_g_mbus_fmt,
2046}; 2378};
2047 2379
2048static const struct v4l2_subdev_pad_ops adv7604_pad_ops = { 2380static const struct v4l2_subdev_pad_ops adv7604_pad_ops = {
2381 .enum_mbus_code = adv7604_enum_mbus_code,
2382 .get_fmt = adv7604_get_format,
2383 .set_fmt = adv7604_set_format,
2049 .get_edid = adv7604_get_edid, 2384 .get_edid = adv7604_get_edid,
2050 .set_edid = adv7604_set_edid, 2385 .set_edid = adv7604_set_edid,
2386 .dv_timings_cap = adv7604_dv_timings_cap,
2387 .enum_dv_timings = adv7604_enum_dv_timings,
2051}; 2388};
2052 2389
2053static const struct v4l2_subdev_ops adv7604_ops = { 2390static const struct v4l2_subdev_ops adv7604_ops = {
@@ -2096,6 +2433,7 @@ static const struct v4l2_ctrl_config adv7604_ctrl_free_run_color = {
2096static int adv7604_core_init(struct v4l2_subdev *sd) 2433static int adv7604_core_init(struct v4l2_subdev *sd)
2097{ 2434{
2098 struct adv7604_state *state = to_state(sd); 2435 struct adv7604_state *state = to_state(sd);
2436 const struct adv7604_chip_info *info = state->info;
2099 struct adv7604_platform_data *pdata = &state->pdata; 2437 struct adv7604_platform_data *pdata = &state->pdata;
2100 2438
2101 hdmi_write(sd, 0x48, 2439 hdmi_write(sd, 0x48,
@@ -2104,28 +2442,33 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
2104 2442
2105 disable_input(sd); 2443 disable_input(sd);
2106 2444
2445 if (pdata->default_input >= 0 &&
2446 pdata->default_input < state->source_pad) {
2447 state->selected_input = pdata->default_input;
2448 select_input(sd);
2449 enable_input(sd);
2450 }
2451
2107 /* power */ 2452 /* power */
2108 io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */ 2453 io_write(sd, 0x0c, 0x42); /* Power up part and power down VDP */
2109 io_write(sd, 0x0b, 0x44); /* Power down ESDP block */ 2454 io_write(sd, 0x0b, 0x44); /* Power down ESDP block */
2110 cp_write(sd, 0xcf, 0x01); /* Power down macrovision */ 2455 cp_write(sd, 0xcf, 0x01); /* Power down macrovision */
2111 2456
2112 /* video format */ 2457 /* video format */
2113 io_write_and_or(sd, 0x02, 0xf0, 2458 io_write_clr_set(sd, 0x02, 0x0f,
2114 pdata->alt_gamma << 3 | 2459 pdata->alt_gamma << 3 |
2115 pdata->op_656_range << 2 | 2460 pdata->op_656_range << 2 |
2116 pdata->rgb_out << 1 |
2117 pdata->alt_data_sat << 0); 2461 pdata->alt_data_sat << 0);
2118 io_write(sd, 0x03, pdata->op_format_sel); 2462 io_write_clr_set(sd, 0x05, 0x0e, pdata->blank_data << 3 |
2119 io_write_and_or(sd, 0x04, 0x1f, pdata->op_ch_sel << 5); 2463 pdata->insert_av_codes << 2 |
2120 io_write_and_or(sd, 0x05, 0xf0, pdata->blank_data << 3 | 2464 pdata->replicate_av_codes << 1);
2121 pdata->insert_av_codes << 2 | 2465 adv7604_setup_format(state);
2122 pdata->replicate_av_codes << 1 |
2123 pdata->invert_cbcr << 0);
2124 2466
2125 cp_write(sd, 0x69, 0x30); /* Enable CP CSC */ 2467 cp_write(sd, 0x69, 0x30); /* Enable CP CSC */
2126 2468
2127 /* VS, HS polarities */ 2469 /* VS, HS polarities */
2128 io_write(sd, 0x06, 0xa0 | pdata->inv_vs_pol << 2 | pdata->inv_hs_pol << 1); 2470 io_write(sd, 0x06, 0xa0 | pdata->inv_vs_pol << 2 |
2471 pdata->inv_hs_pol << 1 | pdata->inv_llc_pol);
2129 2472
2130 /* Adjust drive strength */ 2473 /* Adjust drive strength */
2131 io_write(sd, 0x14, 0x40 | pdata->dr_str_data << 4 | 2474 io_write(sd, 0x14, 0x40 | pdata->dr_str_data << 4 |
@@ -2142,52 +2485,46 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
2142 for digital formats */ 2485 for digital formats */
2143 2486
2144 /* HDMI audio */ 2487 /* HDMI audio */
2145 hdmi_write_and_or(sd, 0x15, 0xfc, 0x03); /* Mute on FIFO over-/underflow [REF_01, c. 1.2.18] */ 2488 hdmi_write_clr_set(sd, 0x15, 0x03, 0x03); /* Mute on FIFO over-/underflow [REF_01, c. 1.2.18] */
2146 hdmi_write_and_or(sd, 0x1a, 0xf1, 0x08); /* Wait 1 s before unmute */ 2489 hdmi_write_clr_set(sd, 0x1a, 0x0e, 0x08); /* Wait 1 s before unmute */
2147 hdmi_write_and_or(sd, 0x68, 0xf9, 0x06); /* FIFO reset on over-/underflow [REF_01, c. 1.2.19] */ 2490 hdmi_write_clr_set(sd, 0x68, 0x06, 0x06); /* FIFO reset on over-/underflow [REF_01, c. 1.2.19] */
2148 2491
2149 /* TODO from platform data */ 2492 /* TODO from platform data */
2150 afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */ 2493 afe_write(sd, 0xb5, 0x01); /* Setting MCLK to 256Fs */
2151 2494
2152 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ 2495 if (adv7604_has_afe(state)) {
2153 io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); 2496 afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
2497 io_write_clr_set(sd, 0x30, 1 << 4, pdata->output_bus_lsb_to_msb << 4);
2498 }
2154 2499
2155 /* interrupts */ 2500 /* interrupts */
2156 io_write(sd, 0x40, 0xc2); /* Configure INT1 */ 2501 io_write(sd, 0x40, 0xc0 | pdata->int1_config); /* Configure INT1 */
2157 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
2158 io_write(sd, 0x46, 0x98); /* Enable SSPD, STDI and CP unlocked interrupts */ 2502 io_write(sd, 0x46, 0x98); /* Enable SSPD, STDI and CP unlocked interrupts */
2159 io_write(sd, 0x6e, 0xc1); /* Enable V_LOCKED, DE_REGEN_LCK, HDMI_MODE interrupts */ 2503 io_write(sd, 0x6e, info->fmt_change_digital_mask); /* Enable V_LOCKED and DE_REGEN_LCK interrupts */
2160 io_write(sd, 0x73, 0x1e); /* Enable CABLE_DET_A_ST (+5v) interrupts */ 2504 io_write(sd, 0x73, info->cable_det_mask); /* Enable cable detection (+5v) interrupts */
2505 info->setup_irqs(sd);
2161 2506
2162 return v4l2_ctrl_handler_setup(sd->ctrl_handler); 2507 return v4l2_ctrl_handler_setup(sd->ctrl_handler);
2163} 2508}
2164 2509
2510static void adv7604_setup_irqs(struct v4l2_subdev *sd)
2511{
2512 io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
2513}
2514
2515static void adv7611_setup_irqs(struct v4l2_subdev *sd)
2516{
2517 io_write(sd, 0x41, 0xd0); /* STDI irq for any change, disable INT2 */
2518}
2519
2165static void adv7604_unregister_clients(struct adv7604_state *state) 2520static void adv7604_unregister_clients(struct adv7604_state *state)
2166{ 2521{
2167 if (state->i2c_avlink) 2522 unsigned int i;
2168 i2c_unregister_device(state->i2c_avlink); 2523
2169 if (state->i2c_cec) 2524 for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) {
2170 i2c_unregister_device(state->i2c_cec); 2525 if (state->i2c_clients[i])
2171 if (state->i2c_infoframe) 2526 i2c_unregister_device(state->i2c_clients[i]);
2172 i2c_unregister_device(state->i2c_infoframe); 2527 }
2173 if (state->i2c_esdp)
2174 i2c_unregister_device(state->i2c_esdp);
2175 if (state->i2c_dpp)
2176 i2c_unregister_device(state->i2c_dpp);
2177 if (state->i2c_afe)
2178 i2c_unregister_device(state->i2c_afe);
2179 if (state->i2c_repeater)
2180 i2c_unregister_device(state->i2c_repeater);
2181 if (state->i2c_edid)
2182 i2c_unregister_device(state->i2c_edid);
2183 if (state->i2c_hdmi)
2184 i2c_unregister_device(state->i2c_hdmi);
2185 if (state->i2c_test)
2186 i2c_unregister_device(state->i2c_test);
2187 if (state->i2c_cp)
2188 i2c_unregister_device(state->i2c_cp);
2189 if (state->i2c_vdp)
2190 i2c_unregister_device(state->i2c_vdp);
2191} 2528}
2192 2529
2193static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd, 2530static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd,
@@ -2200,15 +2537,219 @@ static struct i2c_client *adv7604_dummy_client(struct v4l2_subdev *sd,
2200 return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); 2537 return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1);
2201} 2538}
2202 2539
2540static const struct adv7604_reg_seq adv7604_recommended_settings_afe[] = {
2541 /* reset ADI recommended settings for HDMI: */
2542 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
2543 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */
2544 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x04 }, /* HDMI filter optimization */
2545 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3d), 0x00 }, /* DDC bus active pull-up control */
2546 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3e), 0x74 }, /* TMDS PLL optimization */
2547 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */
2548 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0x74 }, /* TMDS PLL optimization */
2549 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x63 }, /* TMDS PLL optimization */
2550 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */
2551 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */
2552 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x93), 0x88 }, /* equaliser */
2553 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x94), 0x2e }, /* equaliser */
2554 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x96), 0x00 }, /* enable automatic EQ changing */
2555
2556 /* set ADI recommended settings for digitizer */
2557 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
2558 { ADV7604_REG(ADV7604_PAGE_AFE, 0x12), 0x7b }, /* ADC noise shaping filter controls */
2559 { ADV7604_REG(ADV7604_PAGE_AFE, 0x0c), 0x1f }, /* CP core gain controls */
2560 { ADV7604_REG(ADV7604_PAGE_CP, 0x3e), 0x04 }, /* CP core pre-gain control */
2561 { ADV7604_REG(ADV7604_PAGE_CP, 0xc3), 0x39 }, /* CP coast control. Graphics mode */
2562 { ADV7604_REG(ADV7604_PAGE_CP, 0x40), 0x5c }, /* CP core pre-gain control. Graphics mode */
2563
2564 { ADV7604_REG_SEQ_TERM, 0 },
2565};
2566
2567static const struct adv7604_reg_seq adv7604_recommended_settings_hdmi[] = {
2568 /* set ADI recommended settings for HDMI: */
2569 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
2570 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x0d), 0x84 }, /* HDMI filter optimization */
2571 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3d), 0x10 }, /* DDC bus active pull-up control */
2572 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x3e), 0x39 }, /* TMDS PLL optimization */
2573 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4e), 0x3b }, /* TMDS PLL optimization */
2574 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xb6 }, /* TMDS PLL optimization */
2575 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x03 }, /* TMDS PLL optimization */
2576 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x18 }, /* equaliser */
2577 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x34 }, /* equaliser */
2578 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x93), 0x8b }, /* equaliser */
2579 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x94), 0x2d }, /* equaliser */
2580 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x96), 0x01 }, /* enable automatic EQ changing */
2581
2582 /* reset ADI recommended settings for digitizer */
2583 /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 17. */
2584 { ADV7604_REG(ADV7604_PAGE_AFE, 0x12), 0xfb }, /* ADC noise shaping filter controls */
2585 { ADV7604_REG(ADV7604_PAGE_AFE, 0x0c), 0x0d }, /* CP core gain controls */
2586
2587 { ADV7604_REG_SEQ_TERM, 0 },
2588};
2589
2590static const struct adv7604_reg_seq adv7611_recommended_settings_hdmi[] = {
2591 { ADV7604_REG(ADV7604_PAGE_CP, 0x6c), 0x00 },
2592 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x6f), 0x0c },
2593 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x87), 0x70 },
2594 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x57), 0xda },
2595 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x58), 0x01 },
2596 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x03), 0x98 },
2597 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x4c), 0x44 },
2598 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8d), 0x04 },
2599 { ADV7604_REG(ADV7604_PAGE_HDMI, 0x8e), 0x1e },
2600
2601 { ADV7604_REG_SEQ_TERM, 0 },
2602};
2603
2604static const struct adv7604_chip_info adv7604_chip_info[] = {
2605 [ADV7604] = {
2606 .type = ADV7604,
2607 .has_afe = true,
2608 .max_port = ADV7604_PAD_VGA_COMP,
2609 .num_dv_ports = 4,
2610 .edid_enable_reg = 0x77,
2611 .edid_status_reg = 0x7d,
2612 .lcf_reg = 0xb3,
2613 .tdms_lock_mask = 0xe0,
2614 .cable_det_mask = 0x1e,
2615 .fmt_change_digital_mask = 0xc1,
2616 .formats = adv7604_formats,
2617 .nformats = ARRAY_SIZE(adv7604_formats),
2618 .set_termination = adv7604_set_termination,
2619 .setup_irqs = adv7604_setup_irqs,
2620 .read_hdmi_pixelclock = adv7604_read_hdmi_pixelclock,
2621 .read_cable_det = adv7604_read_cable_det,
2622 .recommended_settings = {
2623 [0] = adv7604_recommended_settings_afe,
2624 [1] = adv7604_recommended_settings_hdmi,
2625 },
2626 .num_recommended_settings = {
2627 [0] = ARRAY_SIZE(adv7604_recommended_settings_afe),
2628 [1] = ARRAY_SIZE(adv7604_recommended_settings_hdmi),
2629 },
2630 .page_mask = BIT(ADV7604_PAGE_IO) | BIT(ADV7604_PAGE_AVLINK) |
2631 BIT(ADV7604_PAGE_CEC) | BIT(ADV7604_PAGE_INFOFRAME) |
2632 BIT(ADV7604_PAGE_ESDP) | BIT(ADV7604_PAGE_DPP) |
2633 BIT(ADV7604_PAGE_AFE) | BIT(ADV7604_PAGE_REP) |
2634 BIT(ADV7604_PAGE_EDID) | BIT(ADV7604_PAGE_HDMI) |
2635 BIT(ADV7604_PAGE_TEST) | BIT(ADV7604_PAGE_CP) |
2636 BIT(ADV7604_PAGE_VDP),
2637 },
2638 [ADV7611] = {
2639 .type = ADV7611,
2640 .has_afe = false,
2641 .max_port = ADV7604_PAD_HDMI_PORT_A,
2642 .num_dv_ports = 1,
2643 .edid_enable_reg = 0x74,
2644 .edid_status_reg = 0x76,
2645 .lcf_reg = 0xa3,
2646 .tdms_lock_mask = 0x43,
2647 .cable_det_mask = 0x01,
2648 .fmt_change_digital_mask = 0x03,
2649 .formats = adv7611_formats,
2650 .nformats = ARRAY_SIZE(adv7611_formats),
2651 .set_termination = adv7611_set_termination,
2652 .setup_irqs = adv7611_setup_irqs,
2653 .read_hdmi_pixelclock = adv7611_read_hdmi_pixelclock,
2654 .read_cable_det = adv7611_read_cable_det,
2655 .recommended_settings = {
2656 [1] = adv7611_recommended_settings_hdmi,
2657 },
2658 .num_recommended_settings = {
2659 [1] = ARRAY_SIZE(adv7611_recommended_settings_hdmi),
2660 },
2661 .page_mask = BIT(ADV7604_PAGE_IO) | BIT(ADV7604_PAGE_CEC) |
2662 BIT(ADV7604_PAGE_INFOFRAME) | BIT(ADV7604_PAGE_AFE) |
2663 BIT(ADV7604_PAGE_REP) | BIT(ADV7604_PAGE_EDID) |
2664 BIT(ADV7604_PAGE_HDMI) | BIT(ADV7604_PAGE_CP),
2665 },
2666};
2667
2668static struct i2c_device_id adv7604_i2c_id[] = {
2669 { "adv7604", (kernel_ulong_t)&adv7604_chip_info[ADV7604] },
2670 { "adv7611", (kernel_ulong_t)&adv7604_chip_info[ADV7611] },
2671 { }
2672};
2673MODULE_DEVICE_TABLE(i2c, adv7604_i2c_id);
2674
2675static struct of_device_id adv7604_of_id[] __maybe_unused = {
2676 { .compatible = "adi,adv7611", .data = &adv7604_chip_info[ADV7611] },
2677 { }
2678};
2679MODULE_DEVICE_TABLE(of, adv7604_of_id);
2680
2681static int adv7604_parse_dt(struct adv7604_state *state)
2682{
2683 struct v4l2_of_endpoint bus_cfg;
2684 struct device_node *endpoint;
2685 struct device_node *np;
2686 unsigned int flags;
2687
2688 np = state->i2c_clients[ADV7604_PAGE_IO]->dev.of_node;
2689
2690 /* Parse the endpoint. */
2691 endpoint = of_graph_get_next_endpoint(np, NULL);
2692 if (!endpoint)
2693 return -EINVAL;
2694
2695 v4l2_of_parse_endpoint(endpoint, &bus_cfg);
2696 of_node_put(endpoint);
2697
2698 flags = bus_cfg.bus.parallel.flags;
2699
2700 if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
2701 state->pdata.inv_hs_pol = 1;
2702
2703 if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
2704 state->pdata.inv_vs_pol = 1;
2705
2706 if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
2707 state->pdata.inv_llc_pol = 1;
2708
2709 if (bus_cfg.bus_type == V4L2_MBUS_BT656) {
2710 state->pdata.insert_av_codes = 1;
2711 state->pdata.op_656_range = 1;
2712 }
2713
2714 /* Disable the interrupt for now as no DT-based board uses it. */
2715 state->pdata.int1_config = ADV7604_INT1_CONFIG_DISABLED;
2716
2717 /* Use the default I2C addresses. */
2718 state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42;
2719 state->pdata.i2c_addresses[ADV7604_PAGE_CEC] = 0x40;
2720 state->pdata.i2c_addresses[ADV7604_PAGE_INFOFRAME] = 0x3e;
2721 state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38;
2722 state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c;
2723 state->pdata.i2c_addresses[ADV7604_PAGE_AFE] = 0x26;
2724 state->pdata.i2c_addresses[ADV7604_PAGE_REP] = 0x32;
2725 state->pdata.i2c_addresses[ADV7604_PAGE_EDID] = 0x36;
2726 state->pdata.i2c_addresses[ADV7604_PAGE_HDMI] = 0x34;
2727 state->pdata.i2c_addresses[ADV7604_PAGE_TEST] = 0x30;
2728 state->pdata.i2c_addresses[ADV7604_PAGE_CP] = 0x22;
2729 state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24;
2730
2731 /* Hardcode the remaining platform data fields. */
2732 state->pdata.disable_pwrdnb = 0;
2733 state->pdata.disable_cable_det_rst = 0;
2734 state->pdata.default_input = -1;
2735 state->pdata.blank_data = 1;
2736 state->pdata.alt_data_sat = 1;
2737 state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
2738 state->pdata.bus_order = ADV7604_BUS_ORDER_RGB;
2739
2740 return 0;
2741}
2742
2203static int adv7604_probe(struct i2c_client *client, 2743static int adv7604_probe(struct i2c_client *client,
2204 const struct i2c_device_id *id) 2744 const struct i2c_device_id *id)
2205{ 2745{
2206 static const struct v4l2_dv_timings cea640x480 = 2746 static const struct v4l2_dv_timings cea640x480 =
2207 V4L2_DV_BT_CEA_640X480P59_94; 2747 V4L2_DV_BT_CEA_640X480P59_94;
2208 struct adv7604_state *state; 2748 struct adv7604_state *state;
2209 struct adv7604_platform_data *pdata = client->dev.platform_data;
2210 struct v4l2_ctrl_handler *hdl; 2749 struct v4l2_ctrl_handler *hdl;
2211 struct v4l2_subdev *sd; 2750 struct v4l2_subdev *sd;
2751 unsigned int i;
2752 u16 val;
2212 int err; 2753 int err;
2213 2754
2214 /* Check if the adapter supports the needed features */ 2755 /* Check if the adapter supports the needed features */
@@ -2223,32 +2764,80 @@ static int adv7604_probe(struct i2c_client *client,
2223 return -ENOMEM; 2764 return -ENOMEM;
2224 } 2765 }
2225 2766
2767 state->i2c_clients[ADV7604_PAGE_IO] = client;
2768
2226 /* initialize variables */ 2769 /* initialize variables */
2227 state->restart_stdi_once = true; 2770 state->restart_stdi_once = true;
2228 state->selected_input = ~0; 2771 state->selected_input = ~0;
2229 2772
2230 /* platform data */ 2773 if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {
2231 if (!pdata) { 2774 const struct of_device_id *oid;
2775
2776 oid = of_match_node(adv7604_of_id, client->dev.of_node);
2777 state->info = oid->data;
2778
2779 err = adv7604_parse_dt(state);
2780 if (err < 0) {
2781 v4l_err(client, "DT parsing error\n");
2782 return err;
2783 }
2784 } else if (client->dev.platform_data) {
2785 struct adv7604_platform_data *pdata = client->dev.platform_data;
2786
2787 state->info = (const struct adv7604_chip_info *)id->driver_data;
2788 state->pdata = *pdata;
2789 } else {
2232 v4l_err(client, "No platform data!\n"); 2790 v4l_err(client, "No platform data!\n");
2233 return -ENODEV; 2791 return -ENODEV;
2234 } 2792 }
2235 state->pdata = *pdata; 2793
2794 /* Request GPIOs. */
2795 for (i = 0; i < state->info->num_dv_ports; ++i) {
2796 state->hpd_gpio[i] =
2797 devm_gpiod_get_index(&client->dev, "hpd", i);
2798 if (IS_ERR(state->hpd_gpio[i]))
2799 continue;
2800
2801 gpiod_direction_output(state->hpd_gpio[i], 0);
2802
2803 v4l_info(client, "Handling HPD %u GPIO\n", i);
2804 }
2805
2236 state->timings = cea640x480; 2806 state->timings = cea640x480;
2807 state->format = adv7604_format_info(state, V4L2_MBUS_FMT_YUYV8_2X8);
2237 2808
2238 sd = &state->sd; 2809 sd = &state->sd;
2239 v4l2_i2c_subdev_init(sd, client, &adv7604_ops); 2810 v4l2_i2c_subdev_init(sd, client, &adv7604_ops);
2811 snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
2812 id->name, i2c_adapter_id(client->adapter),
2813 client->addr);
2240 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 2814 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2241 2815
2242 /* i2c access to adv7604? */ 2816 /*
2243 if (adv_smbus_read_byte_data_check(client, 0xfb, false) != 0x68) { 2817 * Verify that the chip is present. On ADV7604 the RD_INFO register only
2244 v4l2_info(sd, "not an adv7604 on address 0x%x\n", 2818 * identifies the revision, while on ADV7611 it identifies the model as
2245 client->addr << 1); 2819 * well. Use the HDMI slave address on ADV7604 and RD_INFO on ADV7611.
2246 return -ENODEV; 2820 */
2821 if (state->info->type == ADV7604) {
2822 val = adv_smbus_read_byte_data_check(client, 0xfb, false);
2823 if (val != 0x68) {
2824 v4l2_info(sd, "not an adv7604 on address 0x%x\n",
2825 client->addr << 1);
2826 return -ENODEV;
2827 }
2828 } else {
2829 val = (adv_smbus_read_byte_data_check(client, 0xea, false) << 8)
2830 | (adv_smbus_read_byte_data_check(client, 0xeb, false) << 0);
2831 if (val != 0x2051) {
2832 v4l2_info(sd, "not an adv7611 on address 0x%x\n",
2833 client->addr << 1);
2834 return -ENODEV;
2835 }
2247 } 2836 }
2248 2837
2249 /* control handlers */ 2838 /* control handlers */
2250 hdl = &state->hdl; 2839 hdl = &state->hdl;
2251 v4l2_ctrl_handler_init(hdl, 9); 2840 v4l2_ctrl_handler_init(hdl, adv7604_has_afe(state) ? 9 : 8);
2252 2841
2253 v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops, 2842 v4l2_ctrl_new_std(hdl, &adv7604_ctrl_ops,
2254 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); 2843 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
@@ -2261,15 +2850,17 @@ static int adv7604_probe(struct i2c_client *client,
2261 2850
2262 /* private controls */ 2851 /* private controls */
2263 state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL, 2852 state->detect_tx_5v_ctrl = v4l2_ctrl_new_std(hdl, NULL,
2264 V4L2_CID_DV_RX_POWER_PRESENT, 0, 0x0f, 0, 0); 2853 V4L2_CID_DV_RX_POWER_PRESENT, 0,
2854 (1 << state->info->num_dv_ports) - 1, 0, 0);
2265 state->rgb_quantization_range_ctrl = 2855 state->rgb_quantization_range_ctrl =
2266 v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops, 2856 v4l2_ctrl_new_std_menu(hdl, &adv7604_ctrl_ops,
2267 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 2857 V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL,
2268 0, V4L2_DV_RGB_RANGE_AUTO); 2858 0, V4L2_DV_RGB_RANGE_AUTO);
2269 2859
2270 /* custom controls */ 2860 /* custom controls */
2271 state->analog_sampling_phase_ctrl = 2861 if (adv7604_has_afe(state))
2272 v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL); 2862 state->analog_sampling_phase_ctrl =
2863 v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_analog_sampling_phase, NULL);
2273 state->free_run_color_manual_ctrl = 2864 state->free_run_color_manual_ctrl =
2274 v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color_manual, NULL); 2865 v4l2_ctrl_new_custom(hdl, &adv7604_ctrl_free_run_color_manual, NULL);
2275 state->free_run_color_ctrl = 2866 state->free_run_color_ctrl =
@@ -2282,7 +2873,8 @@ static int adv7604_probe(struct i2c_client *client,
2282 } 2873 }
2283 state->detect_tx_5v_ctrl->is_private = true; 2874 state->detect_tx_5v_ctrl->is_private = true;
2284 state->rgb_quantization_range_ctrl->is_private = true; 2875 state->rgb_quantization_range_ctrl->is_private = true;
2285 state->analog_sampling_phase_ctrl->is_private = true; 2876 if (adv7604_has_afe(state))
2877 state->analog_sampling_phase_ctrl->is_private = true;
2286 state->free_run_color_manual_ctrl->is_private = true; 2878 state->free_run_color_manual_ctrl->is_private = true;
2287 state->free_run_color_ctrl->is_private = true; 2879 state->free_run_color_ctrl->is_private = true;
2288 2880
@@ -2291,25 +2883,18 @@ static int adv7604_probe(struct i2c_client *client,
2291 goto err_hdl; 2883 goto err_hdl;
2292 } 2884 }
2293 2885
2294 state->i2c_avlink = adv7604_dummy_client(sd, pdata->i2c_avlink, 0xf3); 2886 for (i = 1; i < ADV7604_PAGE_MAX; ++i) {
2295 state->i2c_cec = adv7604_dummy_client(sd, pdata->i2c_cec, 0xf4); 2887 if (!(BIT(i) & state->info->page_mask))
2296 state->i2c_infoframe = adv7604_dummy_client(sd, pdata->i2c_infoframe, 0xf5); 2888 continue;
2297 state->i2c_esdp = adv7604_dummy_client(sd, pdata->i2c_esdp, 0xf6); 2889
2298 state->i2c_dpp = adv7604_dummy_client(sd, pdata->i2c_dpp, 0xf7); 2890 state->i2c_clients[i] =
2299 state->i2c_afe = adv7604_dummy_client(sd, pdata->i2c_afe, 0xf8); 2891 adv7604_dummy_client(sd, state->pdata.i2c_addresses[i],
2300 state->i2c_repeater = adv7604_dummy_client(sd, pdata->i2c_repeater, 0xf9); 2892 0xf2 + i);
2301 state->i2c_edid = adv7604_dummy_client(sd, pdata->i2c_edid, 0xfa); 2893 if (state->i2c_clients[i] == NULL) {
2302 state->i2c_hdmi = adv7604_dummy_client(sd, pdata->i2c_hdmi, 0xfb); 2894 err = -ENOMEM;
2303 state->i2c_test = adv7604_dummy_client(sd, pdata->i2c_test, 0xfc); 2895 v4l2_err(sd, "failed to create i2c client %u\n", i);
2304 state->i2c_cp = adv7604_dummy_client(sd, pdata->i2c_cp, 0xfd); 2896 goto err_i2c;
2305 state->i2c_vdp = adv7604_dummy_client(sd, pdata->i2c_vdp, 0xfe); 2897 }
2306 if (!state->i2c_avlink || !state->i2c_cec || !state->i2c_infoframe ||
2307 !state->i2c_esdp || !state->i2c_dpp || !state->i2c_afe ||
2308 !state->i2c_repeater || !state->i2c_edid || !state->i2c_hdmi ||
2309 !state->i2c_test || !state->i2c_cp || !state->i2c_vdp) {
2310 err = -ENOMEM;
2311 v4l2_err(sd, "failed to create all i2c clients\n");
2312 goto err_i2c;
2313 } 2898 }
2314 2899
2315 /* work queues */ 2900 /* work queues */
@@ -2323,8 +2908,14 @@ static int adv7604_probe(struct i2c_client *client,
2323 INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug, 2908 INIT_DELAYED_WORK(&state->delayed_work_enable_hotplug,
2324 adv7604_delayed_work_enable_hotplug); 2909 adv7604_delayed_work_enable_hotplug);
2325 2910
2326 state->pad.flags = MEDIA_PAD_FL_SOURCE; 2911 state->source_pad = state->info->num_dv_ports
2327 err = media_entity_init(&sd->entity, 1, &state->pad, 0); 2912 + (state->info->has_afe ? 2 : 0);
2913 for (i = 0; i < state->source_pad; ++i)
2914 state->pads[i].flags = MEDIA_PAD_FL_SINK;
2915 state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
2916
2917 err = media_entity_init(&sd->entity, state->source_pad + 1,
2918 state->pads, 0);
2328 if (err) 2919 if (err)
2329 goto err_work_queues; 2920 goto err_work_queues;
2330 2921
@@ -2333,6 +2924,11 @@ static int adv7604_probe(struct i2c_client *client,
2333 goto err_entity; 2924 goto err_entity;
2334 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, 2925 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
2335 client->addr << 1, client->adapter->name); 2926 client->addr << 1, client->adapter->name);
2927
2928 err = v4l2_async_register_subdev(sd);
2929 if (err)
2930 goto err_entity;
2931
2336 return 0; 2932 return 0;
2337 2933
2338err_entity: 2934err_entity:
@@ -2356,6 +2952,7 @@ static int adv7604_remove(struct i2c_client *client)
2356 2952
2357 cancel_delayed_work(&state->delayed_work_enable_hotplug); 2953 cancel_delayed_work(&state->delayed_work_enable_hotplug);
2358 destroy_workqueue(state->work_queues); 2954 destroy_workqueue(state->work_queues);
2955 v4l2_async_unregister_subdev(sd);
2359 v4l2_device_unregister_subdev(sd); 2956 v4l2_device_unregister_subdev(sd);
2360 media_entity_cleanup(&sd->entity); 2957 media_entity_cleanup(&sd->entity);
2361 adv7604_unregister_clients(to_state(sd)); 2958 adv7604_unregister_clients(to_state(sd));
@@ -2365,20 +2962,15 @@ static int adv7604_remove(struct i2c_client *client)
2365 2962
2366/* ----------------------------------------------------------------------- */ 2963/* ----------------------------------------------------------------------- */
2367 2964
2368static struct i2c_device_id adv7604_id[] = {
2369 { "adv7604", 0 },
2370 { }
2371};
2372MODULE_DEVICE_TABLE(i2c, adv7604_id);
2373
2374static struct i2c_driver adv7604_driver = { 2965static struct i2c_driver adv7604_driver = {
2375 .driver = { 2966 .driver = {
2376 .owner = THIS_MODULE, 2967 .owner = THIS_MODULE,
2377 .name = "adv7604", 2968 .name = "adv7604",
2969 .of_match_table = of_match_ptr(adv7604_of_id),
2378 }, 2970 },
2379 .probe = adv7604_probe, 2971 .probe = adv7604_probe,
2380 .remove = adv7604_remove, 2972 .remove = adv7604_remove,
2381 .id_table = adv7604_id, 2973 .id_table = adv7604_i2c_id,
2382}; 2974};
2383 2975
2384module_i2c_driver(adv7604_driver); 2976module_i2c_driver(adv7604_driver);
diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile
index 151cecd0ea25..6a93f928dfde 100644
--- a/drivers/media/platform/vsp1/Makefile
+++ b/drivers/media/platform/vsp1/Makefile
@@ -1,6 +1,6 @@
1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_video.o 1vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_video.o
2vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o 2vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o
3vsp1-y += vsp1_hsit.o vsp1_lif.o vsp1_lut.o 3vsp1-y += vsp1_hsit.o vsp1_lif.o vsp1_lut.o
4vsp1-y += vsp1_sru.o vsp1_uds.o 4vsp1-y += vsp1_bru.o vsp1_sru.o vsp1_uds.o
5 5
6obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o 6obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 0313210c6e9e..6ca2cf20d545 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -28,6 +28,7 @@ struct clk;
28struct device; 28struct device;
29 29
30struct vsp1_platform_data; 30struct vsp1_platform_data;
31struct vsp1_bru;
31struct vsp1_hsit; 32struct vsp1_hsit;
32struct vsp1_lif; 33struct vsp1_lif;
33struct vsp1_lut; 34struct vsp1_lut;
@@ -45,11 +46,11 @@ struct vsp1_device {
45 46
46 void __iomem *mmio; 47 void __iomem *mmio;
47 struct clk *clock; 48 struct clk *clock;
48 struct clk *rt_clock;
49 49
50 struct mutex lock; 50 struct mutex lock;
51 int ref_count; 51 int ref_count;
52 52
53 struct vsp1_bru *bru;
53 struct vsp1_hsit *hsi; 54 struct vsp1_hsit *hsi;
54 struct vsp1_hsit *hst; 55 struct vsp1_hsit *hst;
55 struct vsp1_lif *lif; 56 struct vsp1_lif *lif;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
new file mode 100644
index 000000000000..f80695480060
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -0,0 +1,395 @@
1/*
2 * vsp1_bru.c -- R-Car VSP1 Blend ROP Unit
3 *
4 * Copyright (C) 2013 Renesas Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/gfp.h>
16
17#include <media/v4l2-subdev.h>
18
19#include "vsp1.h"
20#include "vsp1_bru.h"
21
22#define BRU_MIN_SIZE 4U
23#define BRU_MAX_SIZE 8190U
24
25/* -----------------------------------------------------------------------------
26 * Device Access
27 */
28
29static inline u32 vsp1_bru_read(struct vsp1_bru *bru, u32 reg)
30{
31 return vsp1_read(bru->entity.vsp1, reg);
32}
33
34static inline void vsp1_bru_write(struct vsp1_bru *bru, u32 reg, u32 data)
35{
36 vsp1_write(bru->entity.vsp1, reg, data);
37}
38
39/* -----------------------------------------------------------------------------
40 * V4L2 Subdevice Core Operations
41 */
42
43static bool bru_is_input_enabled(struct vsp1_bru *bru, unsigned int input)
44{
45 return media_entity_remote_pad(&bru->entity.pads[input]) != NULL;
46}
47
48static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
49{
50 struct vsp1_bru *bru = to_bru(subdev);
51 struct v4l2_mbus_framefmt *format;
52 unsigned int i;
53
54 if (!enable)
55 return 0;
56
57 format = &bru->entity.formats[BRU_PAD_SOURCE];
58
59 /* The hardware is extremely flexible but we have no userspace API to
60 * expose all the parameters, nor is it clear whether we would have use
61 * cases for all the supported modes. Let's just harcode the parameters
62 * to sane default values for now.
63 */
64
65 /* Disable both color data normalization and dithering. */
66 vsp1_bru_write(bru, VI6_BRU_INCTRL, 0);
67
68 /* Set the background position to cover the whole output image and
69 * set its color to opaque black.
70 */
71 vsp1_bru_write(bru, VI6_BRU_VIRRPF_SIZE,
72 (format->width << VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT) |
73 (format->height << VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT));
74 vsp1_bru_write(bru, VI6_BRU_VIRRPF_LOC, 0);
75 vsp1_bru_write(bru, VI6_BRU_VIRRPF_COL,
76 0xff << VI6_BRU_VIRRPF_COL_A_SHIFT);
77
78 /* Route BRU input 1 as SRC input to the ROP unit and configure the ROP
79 * unit with a NOP operation to make BRU input 1 available as the
80 * Blend/ROP unit B SRC input.
81 */
82 vsp1_bru_write(bru, VI6_BRU_ROP, VI6_BRU_ROP_DSTSEL_BRUIN(1) |
83 VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
84 VI6_BRU_ROP_AROP(VI6_ROP_NOP));
85
86 for (i = 0; i < 4; ++i) {
87 u32 ctrl = 0;
88
89 /* Configure all Blend/ROP units corresponding to an enabled BRU
90 * input for alpha blending. Blend/ROP units corresponding to
91 * disabled BRU inputs are used in ROP NOP mode to ignore the
92 * SRC input.
93 */
94 if (bru_is_input_enabled(bru, i))
95 ctrl |= VI6_BRU_CTRL_RBC;
96 else
97 ctrl |= VI6_BRU_CTRL_CROP(VI6_ROP_NOP)
98 | VI6_BRU_CTRL_AROP(VI6_ROP_NOP);
99
100 /* Select the virtual RPF as the Blend/ROP unit A DST input to
101 * serve as a background color.
102 */
103 if (i == 0)
104 ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;
105
106 /* Route BRU inputs 0 to 3 as SRC inputs to Blend/ROP units A to
107 * D in that order. The Blend/ROP unit B SRC is hardwired to the
108 * ROP unit output, the corresponding register bits must be set
109 * to 0.
110 */
111 if (i != 1)
112 ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);
113
114 vsp1_bru_write(bru, VI6_BRU_CTRL(i), ctrl);
115
116 /* Harcode the blending formula to
117 *
118 * DSTc = DSTc * (1 - SRCa) + SRCc * SRCa
119 * DSTa = DSTa * (1 - SRCa) + SRCa
120 */
121 vsp1_bru_write(bru, VI6_BRU_BLD(i),
122 VI6_BRU_BLD_CCMDX_255_SRC_A |
123 VI6_BRU_BLD_CCMDY_SRC_A |
124 VI6_BRU_BLD_ACMDX_255_SRC_A |
125 VI6_BRU_BLD_ACMDY_COEFY |
126 (0xff << VI6_BRU_BLD_COEFY_SHIFT));
127 }
128
129 return 0;
130}
131
132/* -----------------------------------------------------------------------------
133 * V4L2 Subdevice Pad Operations
134 */
135
136/*
137 * The BRU can't perform format conversion, all sink and source formats must be
138 * identical. We pick the format on the first sink pad (pad 0) and propagate it
139 * to all other pads.
140 */
141
142static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
143 struct v4l2_subdev_fh *fh,
144 struct v4l2_subdev_mbus_code_enum *code)
145{
146 static const unsigned int codes[] = {
147 V4L2_MBUS_FMT_ARGB8888_1X32,
148 V4L2_MBUS_FMT_AYUV8_1X32,
149 };
150 struct v4l2_mbus_framefmt *format;
151
152 if (code->pad == BRU_PAD_SINK(0)) {
153 if (code->index >= ARRAY_SIZE(codes))
154 return -EINVAL;
155
156 code->code = codes[code->index];
157 } else {
158 if (code->index)
159 return -EINVAL;
160
161 format = v4l2_subdev_get_try_format(fh, BRU_PAD_SINK(0));
162 code->code = format->code;
163 }
164
165 return 0;
166}
167
168static int bru_enum_frame_size(struct v4l2_subdev *subdev,
169 struct v4l2_subdev_fh *fh,
170 struct v4l2_subdev_frame_size_enum *fse)
171{
172 if (fse->index)
173 return -EINVAL;
174
175 if (fse->code != V4L2_MBUS_FMT_ARGB8888_1X32 &&
176 fse->code != V4L2_MBUS_FMT_AYUV8_1X32)
177 return -EINVAL;
178
179 fse->min_width = BRU_MIN_SIZE;
180 fse->max_width = BRU_MAX_SIZE;
181 fse->min_height = BRU_MIN_SIZE;
182 fse->max_height = BRU_MAX_SIZE;
183
184 return 0;
185}
186
187static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru,
188 struct v4l2_subdev_fh *fh,
189 unsigned int pad, u32 which)
190{
191 switch (which) {
192 case V4L2_SUBDEV_FORMAT_TRY:
193 return v4l2_subdev_get_try_crop(fh, pad);
194 case V4L2_SUBDEV_FORMAT_ACTIVE:
195 return &bru->compose[pad];
196 default:
197 return NULL;
198 }
199}
200
201static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
202 struct v4l2_subdev_format *fmt)
203{
204 struct vsp1_bru *bru = to_bru(subdev);
205
206 fmt->format = *vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad,
207 fmt->which);
208
209 return 0;
210}
211
212static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh,
213 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
214 enum v4l2_subdev_format_whence which)
215{
216 struct v4l2_mbus_framefmt *format;
217
218 switch (pad) {
219 case BRU_PAD_SINK(0):
220 /* Default to YUV if the requested format is not supported. */
221 if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 &&
222 fmt->code != V4L2_MBUS_FMT_AYUV8_1X32)
223 fmt->code = V4L2_MBUS_FMT_AYUV8_1X32;
224 break;
225
226 default:
227 /* The BRU can't perform format conversion. */
228 format = vsp1_entity_get_pad_format(&bru->entity, fh,
229 BRU_PAD_SINK(0), which);
230 fmt->code = format->code;
231 break;
232 }
233
234 fmt->width = clamp(fmt->width, BRU_MIN_SIZE, BRU_MAX_SIZE);
235 fmt->height = clamp(fmt->height, BRU_MIN_SIZE, BRU_MAX_SIZE);
236 fmt->field = V4L2_FIELD_NONE;
237 fmt->colorspace = V4L2_COLORSPACE_SRGB;
238}
239
240static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
241 struct v4l2_subdev_format *fmt)
242{
243 struct vsp1_bru *bru = to_bru(subdev);
244 struct v4l2_mbus_framefmt *format;
245
246 bru_try_format(bru, fh, fmt->pad, &fmt->format, fmt->which);
247
248 format = vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad,
249 fmt->which);
250 *format = fmt->format;
251
252 /* Reset the compose rectangle */
253 if (fmt->pad != BRU_PAD_SOURCE) {
254 struct v4l2_rect *compose;
255
256 compose = bru_get_compose(bru, fh, fmt->pad, fmt->which);
257 compose->left = 0;
258 compose->top = 0;
259 compose->width = format->width;
260 compose->height = format->height;
261 }
262
263 /* Propagate the format code to all pads */
264 if (fmt->pad == BRU_PAD_SINK(0)) {
265 unsigned int i;
266
267 for (i = 0; i <= BRU_PAD_SOURCE; ++i) {
268 format = vsp1_entity_get_pad_format(&bru->entity, fh,
269 i, fmt->which);
270 format->code = fmt->format.code;
271 }
272 }
273
274 return 0;
275}
276
277static int bru_get_selection(struct v4l2_subdev *subdev,
278 struct v4l2_subdev_fh *fh,
279 struct v4l2_subdev_selection *sel)
280{
281 struct vsp1_bru *bru = to_bru(subdev);
282
283 if (sel->pad == BRU_PAD_SOURCE)
284 return -EINVAL;
285
286 switch (sel->target) {
287 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
288 sel->r.left = 0;
289 sel->r.top = 0;
290 sel->r.width = BRU_MAX_SIZE;
291 sel->r.height = BRU_MAX_SIZE;
292 return 0;
293
294 case V4L2_SEL_TGT_COMPOSE:
295 sel->r = *bru_get_compose(bru, fh, sel->pad, sel->which);
296 return 0;
297
298 default:
299 return -EINVAL;
300 }
301}
302
303static int bru_set_selection(struct v4l2_subdev *subdev,
304 struct v4l2_subdev_fh *fh,
305 struct v4l2_subdev_selection *sel)
306{
307 struct vsp1_bru *bru = to_bru(subdev);
308 struct v4l2_mbus_framefmt *format;
309 struct v4l2_rect *compose;
310
311 if (sel->pad == BRU_PAD_SOURCE)
312 return -EINVAL;
313
314 if (sel->target != V4L2_SEL_TGT_COMPOSE)
315 return -EINVAL;
316
317 /* The compose rectangle top left corner must be inside the output
318 * frame.
319 */
320 format = vsp1_entity_get_pad_format(&bru->entity, fh, BRU_PAD_SOURCE,
321 sel->which);
322 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
323 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
324
325 /* Scaling isn't supported, the compose rectangle size must be identical
326 * to the sink format size.
327 */
328 format = vsp1_entity_get_pad_format(&bru->entity, fh, sel->pad,
329 sel->which);
330 sel->r.width = format->width;
331 sel->r.height = format->height;
332
333 compose = bru_get_compose(bru, fh, sel->pad, sel->which);
334 *compose = sel->r;
335
336 return 0;
337}
338
339/* -----------------------------------------------------------------------------
340 * V4L2 Subdevice Operations
341 */
342
343static struct v4l2_subdev_video_ops bru_video_ops = {
344 .s_stream = bru_s_stream,
345};
346
347static struct v4l2_subdev_pad_ops bru_pad_ops = {
348 .enum_mbus_code = bru_enum_mbus_code,
349 .enum_frame_size = bru_enum_frame_size,
350 .get_fmt = bru_get_format,
351 .set_fmt = bru_set_format,
352 .get_selection = bru_get_selection,
353 .set_selection = bru_set_selection,
354};
355
356static struct v4l2_subdev_ops bru_ops = {
357 .video = &bru_video_ops,
358 .pad = &bru_pad_ops,
359};
360
361/* -----------------------------------------------------------------------------
362 * Initialization and Cleanup
363 */
364
365struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1)
366{
367 struct v4l2_subdev *subdev;
368 struct vsp1_bru *bru;
369 int ret;
370
371 bru = devm_kzalloc(vsp1->dev, sizeof(*bru), GFP_KERNEL);
372 if (bru == NULL)
373 return ERR_PTR(-ENOMEM);
374
375 bru->entity.type = VSP1_ENTITY_BRU;
376
377 ret = vsp1_entity_init(vsp1, &bru->entity, 5);
378 if (ret < 0)
379 return ERR_PTR(ret);
380
381 /* Initialize the V4L2 subdev. */
382 subdev = &bru->entity.subdev;
383 v4l2_subdev_init(subdev, &bru_ops);
384
385 subdev->entity.ops = &vsp1_media_ops;
386 subdev->internal_ops = &vsp1_subdev_internal_ops;
387 snprintf(subdev->name, sizeof(subdev->name), "%s bru",
388 dev_name(vsp1->dev));
389 v4l2_set_subdevdata(subdev, bru);
390 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
391
392 vsp1_entity_init_formats(subdev, NULL);
393
394 return bru;
395}
diff --git a/drivers/media/platform/vsp1/vsp1_bru.h b/drivers/media/platform/vsp1/vsp1_bru.h
new file mode 100644
index 000000000000..37062704dbf6
--- /dev/null
+++ b/drivers/media/platform/vsp1/vsp1_bru.h
@@ -0,0 +1,39 @@
1/*
2 * vsp1_bru.h -- R-Car VSP1 Blend ROP Unit
3 *
4 * Copyright (C) 2013 Renesas Corporation
5 *
6 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#ifndef __VSP1_BRU_H__
14#define __VSP1_BRU_H__
15
16#include <media/media-entity.h>
17#include <media/v4l2-subdev.h>
18
19#include "vsp1_entity.h"
20
21struct vsp1_device;
22
23#define BRU_PAD_SINK(n) (n)
24#define BRU_PAD_SOURCE 4
25
26struct vsp1_bru {
27 struct vsp1_entity entity;
28
29 struct v4l2_rect compose[4];
30};
31
32static inline struct vsp1_bru *to_bru(struct v4l2_subdev *subdev)
33{
34 return container_of(subdev, struct vsp1_bru, entity.subdev);
35}
36
37struct vsp1_bru *vsp1_bru_create(struct vsp1_device *vsp1);
38
39#endif /* __VSP1_BRU_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 2f74f0e0ddf5..c69ee0657f75 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -16,10 +16,12 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/of.h>
19#include <linux/platform_device.h> 20#include <linux/platform_device.h>
20#include <linux/videodev2.h> 21#include <linux/videodev2.h>
21 22
22#include "vsp1.h" 23#include "vsp1.h"
24#include "vsp1_bru.h"
23#include "vsp1_hsit.h" 25#include "vsp1_hsit.h"
24#include "vsp1_lif.h" 26#include "vsp1_lif.h"
25#include "vsp1_lut.h" 27#include "vsp1_lut.h"
@@ -155,6 +157,14 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
155 } 157 }
156 158
157 /* Instantiate all the entities. */ 159 /* Instantiate all the entities. */
160 vsp1->bru = vsp1_bru_create(vsp1);
161 if (IS_ERR(vsp1->bru)) {
162 ret = PTR_ERR(vsp1->bru);
163 goto done;
164 }
165
166 list_add_tail(&vsp1->bru->entity.list_dev, &vsp1->entities);
167
158 vsp1->hsi = vsp1_hsit_create(vsp1, true); 168 vsp1->hsi = vsp1_hsit_create(vsp1, true);
159 if (IS_ERR(vsp1->hsi)) { 169 if (IS_ERR(vsp1->hsi)) {
160 ret = PTR_ERR(vsp1->hsi); 170 ret = PTR_ERR(vsp1->hsi);
@@ -329,33 +339,6 @@ static int vsp1_device_init(struct vsp1_device *vsp1)
329 return 0; 339 return 0;
330} 340}
331 341
332static int vsp1_clocks_enable(struct vsp1_device *vsp1)
333{
334 int ret;
335
336 ret = clk_prepare_enable(vsp1->clock);
337 if (ret < 0)
338 return ret;
339
340 if (IS_ERR(vsp1->rt_clock))
341 return 0;
342
343 ret = clk_prepare_enable(vsp1->rt_clock);
344 if (ret < 0) {
345 clk_disable_unprepare(vsp1->clock);
346 return ret;
347 }
348
349 return 0;
350}
351
352static void vsp1_clocks_disable(struct vsp1_device *vsp1)
353{
354 if (!IS_ERR(vsp1->rt_clock))
355 clk_disable_unprepare(vsp1->rt_clock);
356 clk_disable_unprepare(vsp1->clock);
357}
358
359/* 342/*
360 * vsp1_device_get - Acquire the VSP1 device 343 * vsp1_device_get - Acquire the VSP1 device
361 * 344 *
@@ -373,7 +356,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
373 if (vsp1->ref_count > 0) 356 if (vsp1->ref_count > 0)
374 goto done; 357 goto done;
375 358
376 ret = vsp1_clocks_enable(vsp1); 359 ret = clk_prepare_enable(vsp1->clock);
377 if (ret < 0) { 360 if (ret < 0) {
378 __vsp1 = NULL; 361 __vsp1 = NULL;
379 goto done; 362 goto done;
@@ -381,7 +364,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1)
381 364
382 ret = vsp1_device_init(vsp1); 365 ret = vsp1_device_init(vsp1);
383 if (ret < 0) { 366 if (ret < 0) {
384 vsp1_clocks_disable(vsp1); 367 clk_disable_unprepare(vsp1->clock);
385 __vsp1 = NULL; 368 __vsp1 = NULL;
386 goto done; 369 goto done;
387 } 370 }
@@ -405,7 +388,7 @@ void vsp1_device_put(struct vsp1_device *vsp1)
405 mutex_lock(&vsp1->lock); 388 mutex_lock(&vsp1->lock);
406 389
407 if (--vsp1->ref_count == 0) 390 if (--vsp1->ref_count == 0)
408 vsp1_clocks_disable(vsp1); 391 clk_disable_unprepare(vsp1->clock);
409 392
410 mutex_unlock(&vsp1->lock); 393 mutex_unlock(&vsp1->lock);
411} 394}
@@ -424,7 +407,7 @@ static int vsp1_pm_suspend(struct device *dev)
424 if (vsp1->ref_count == 0) 407 if (vsp1->ref_count == 0)
425 return 0; 408 return 0;
426 409
427 vsp1_clocks_disable(vsp1); 410 clk_disable_unprepare(vsp1->clock);
428 return 0; 411 return 0;
429} 412}
430 413
@@ -437,7 +420,7 @@ static int vsp1_pm_resume(struct device *dev)
437 if (vsp1->ref_count) 420 if (vsp1->ref_count)
438 return 0; 421 return 0;
439 422
440 return vsp1_clocks_enable(vsp1); 423 return clk_prepare_enable(vsp1->clock);
441} 424}
442#endif 425#endif
443 426
@@ -449,34 +432,59 @@ static const struct dev_pm_ops vsp1_pm_ops = {
449 * Platform Driver 432 * Platform Driver
450 */ 433 */
451 434
452static struct vsp1_platform_data * 435static int vsp1_validate_platform_data(struct platform_device *pdev,
453vsp1_get_platform_data(struct platform_device *pdev) 436 struct vsp1_platform_data *pdata)
454{ 437{
455 struct vsp1_platform_data *pdata = pdev->dev.platform_data;
456
457 if (pdata == NULL) { 438 if (pdata == NULL) {
458 dev_err(&pdev->dev, "missing platform data\n"); 439 dev_err(&pdev->dev, "missing platform data\n");
459 return NULL; 440 return -EINVAL;
460 } 441 }
461 442
462 if (pdata->rpf_count <= 0 || pdata->rpf_count > VPS1_MAX_RPF) { 443 if (pdata->rpf_count <= 0 || pdata->rpf_count > VPS1_MAX_RPF) {
463 dev_err(&pdev->dev, "invalid number of RPF (%u)\n", 444 dev_err(&pdev->dev, "invalid number of RPF (%u)\n",
464 pdata->rpf_count); 445 pdata->rpf_count);
465 return NULL; 446 return -EINVAL;
466 } 447 }
467 448
468 if (pdata->uds_count <= 0 || pdata->uds_count > VPS1_MAX_UDS) { 449 if (pdata->uds_count <= 0 || pdata->uds_count > VPS1_MAX_UDS) {
469 dev_err(&pdev->dev, "invalid number of UDS (%u)\n", 450 dev_err(&pdev->dev, "invalid number of UDS (%u)\n",
470 pdata->uds_count); 451 pdata->uds_count);
471 return NULL; 452 return -EINVAL;
472 } 453 }
473 454
474 if (pdata->wpf_count <= 0 || pdata->wpf_count > VPS1_MAX_WPF) { 455 if (pdata->wpf_count <= 0 || pdata->wpf_count > VPS1_MAX_WPF) {
475 dev_err(&pdev->dev, "invalid number of WPF (%u)\n", 456 dev_err(&pdev->dev, "invalid number of WPF (%u)\n",
476 pdata->wpf_count); 457 pdata->wpf_count);
477 return NULL; 458 return -EINVAL;
478 } 459 }
479 460
461 return 0;
462}
463
464static struct vsp1_platform_data *
465vsp1_get_platform_data(struct platform_device *pdev)
466{
467 struct device_node *np = pdev->dev.of_node;
468 struct vsp1_platform_data *pdata;
469
470 if (!IS_ENABLED(CONFIG_OF) || np == NULL)
471 return pdev->dev.platform_data;
472
473 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
474 if (pdata == NULL)
475 return NULL;
476
477 if (of_property_read_bool(np, "renesas,has-lif"))
478 pdata->features |= VSP1_HAS_LIF;
479 if (of_property_read_bool(np, "renesas,has-lut"))
480 pdata->features |= VSP1_HAS_LUT;
481 if (of_property_read_bool(np, "renesas,has-sru"))
482 pdata->features |= VSP1_HAS_SRU;
483
484 of_property_read_u32(np, "renesas,#rpf", &pdata->rpf_count);
485 of_property_read_u32(np, "renesas,#uds", &pdata->uds_count);
486 of_property_read_u32(np, "renesas,#wpf", &pdata->wpf_count);
487
480 return pdata; 488 return pdata;
481} 489}
482 490
@@ -499,6 +507,10 @@ static int vsp1_probe(struct platform_device *pdev)
499 if (vsp1->pdata == NULL) 507 if (vsp1->pdata == NULL)
500 return -ENODEV; 508 return -ENODEV;
501 509
510 ret = vsp1_validate_platform_data(pdev, vsp1->pdata);
511 if (ret < 0)
512 return ret;
513
502 /* I/O, IRQ and clock resources */ 514 /* I/O, IRQ and clock resources */
503 io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 515 io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
504 vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); 516 vsp1->mmio = devm_ioremap_resource(&pdev->dev, io);
@@ -511,9 +523,6 @@ static int vsp1_probe(struct platform_device *pdev)
511 return PTR_ERR(vsp1->clock); 523 return PTR_ERR(vsp1->clock);
512 } 524 }
513 525
514 /* The RT clock is optional */
515 vsp1->rt_clock = devm_clk_get(&pdev->dev, "rt");
516
517 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 526 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
518 if (!irq) { 527 if (!irq) {
519 dev_err(&pdev->dev, "missing IRQ\n"); 528 dev_err(&pdev->dev, "missing IRQ\n");
@@ -548,6 +557,11 @@ static int vsp1_remove(struct platform_device *pdev)
548 return 0; 557 return 0;
549} 558}
550 559
560static const struct of_device_id vsp1_of_match[] = {
561 { .compatible = "renesas,vsp1" },
562 { },
563};
564
551static struct platform_driver vsp1_platform_driver = { 565static struct platform_driver vsp1_platform_driver = {
552 .probe = vsp1_probe, 566 .probe = vsp1_probe,
553 .remove = vsp1_remove, 567 .remove = vsp1_remove,
@@ -555,6 +569,7 @@ static struct platform_driver vsp1_platform_driver = {
555 .owner = THIS_MODULE, 569 .owner = THIS_MODULE,
556 .name = "vsp1", 570 .name = "vsp1",
557 .pm = &vsp1_pm_ops, 571 .pm = &vsp1_pm_ops,
572 .of_match_table = vsp1_of_match,
558 }, 573 },
559}; 574};
560 575
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 3fc9e4266caf..44167834285d 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -100,8 +100,10 @@ static int vsp1_entity_link_setup(struct media_entity *entity,
100 if (source->sink) 100 if (source->sink)
101 return -EBUSY; 101 return -EBUSY;
102 source->sink = remote->entity; 102 source->sink = remote->entity;
103 source->sink_pad = remote->index;
103 } else { 104 } else {
104 source->sink = NULL; 105 source->sink = NULL;
106 source->sink_pad = 0;
105 } 107 }
106 108
107 return 0; 109 return 0;
@@ -116,42 +118,43 @@ const struct media_entity_operations vsp1_media_ops = {
116 * Initialization 118 * Initialization
117 */ 119 */
118 120
121static const struct vsp1_route vsp1_routes[] = {
122 { VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
123 { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
124 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), } },
125 { VSP1_ENTITY_HSI, 0, VI6_DPR_HSI_ROUTE, { VI6_DPR_NODE_HSI, } },
126 { VSP1_ENTITY_HST, 0, VI6_DPR_HST_ROUTE, { VI6_DPR_NODE_HST, } },
127 { VSP1_ENTITY_LIF, 0, 0, { VI6_DPR_NODE_LIF, } },
128 { VSP1_ENTITY_LUT, 0, VI6_DPR_LUT_ROUTE, { VI6_DPR_NODE_LUT, } },
129 { VSP1_ENTITY_RPF, 0, VI6_DPR_RPF_ROUTE(0), { VI6_DPR_NODE_RPF(0), } },
130 { VSP1_ENTITY_RPF, 1, VI6_DPR_RPF_ROUTE(1), { VI6_DPR_NODE_RPF(1), } },
131 { VSP1_ENTITY_RPF, 2, VI6_DPR_RPF_ROUTE(2), { VI6_DPR_NODE_RPF(2), } },
132 { VSP1_ENTITY_RPF, 3, VI6_DPR_RPF_ROUTE(3), { VI6_DPR_NODE_RPF(3), } },
133 { VSP1_ENTITY_RPF, 4, VI6_DPR_RPF_ROUTE(4), { VI6_DPR_NODE_RPF(4), } },
134 { VSP1_ENTITY_SRU, 0, VI6_DPR_SRU_ROUTE, { VI6_DPR_NODE_SRU, } },
135 { VSP1_ENTITY_UDS, 0, VI6_DPR_UDS_ROUTE(0), { VI6_DPR_NODE_UDS(0), } },
136 { VSP1_ENTITY_UDS, 1, VI6_DPR_UDS_ROUTE(1), { VI6_DPR_NODE_UDS(1), } },
137 { VSP1_ENTITY_UDS, 2, VI6_DPR_UDS_ROUTE(2), { VI6_DPR_NODE_UDS(2), } },
138 { VSP1_ENTITY_WPF, 0, 0, { VI6_DPR_NODE_WPF(0), } },
139 { VSP1_ENTITY_WPF, 1, 0, { VI6_DPR_NODE_WPF(1), } },
140 { VSP1_ENTITY_WPF, 2, 0, { VI6_DPR_NODE_WPF(2), } },
141 { VSP1_ENTITY_WPF, 3, 0, { VI6_DPR_NODE_WPF(3), } },
142};
143
119int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, 144int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
120 unsigned int num_pads) 145 unsigned int num_pads)
121{ 146{
122 static const struct {
123 unsigned int id;
124 unsigned int reg;
125 } routes[] = {
126 { VI6_DPR_NODE_HSI, VI6_DPR_HSI_ROUTE },
127 { VI6_DPR_NODE_HST, VI6_DPR_HST_ROUTE },
128 { VI6_DPR_NODE_LIF, 0 },
129 { VI6_DPR_NODE_LUT, VI6_DPR_LUT_ROUTE },
130 { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) },
131 { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) },
132 { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) },
133 { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) },
134 { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) },
135 { VI6_DPR_NODE_SRU, VI6_DPR_SRU_ROUTE },
136 { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) },
137 { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) },
138 { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) },
139 { VI6_DPR_NODE_WPF(0), 0 },
140 { VI6_DPR_NODE_WPF(1), 0 },
141 { VI6_DPR_NODE_WPF(2), 0 },
142 { VI6_DPR_NODE_WPF(3), 0 },
143 };
144
145 unsigned int i; 147 unsigned int i;
146 148
147 for (i = 0; i < ARRAY_SIZE(routes); ++i) { 149 for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) {
148 if (routes[i].id == entity->id) { 150 if (vsp1_routes[i].type == entity->type &&
149 entity->route = routes[i].reg; 151 vsp1_routes[i].index == entity->index) {
152 entity->route = &vsp1_routes[i];
150 break; 153 break;
151 } 154 }
152 } 155 }
153 156
154 if (i == ARRAY_SIZE(routes)) 157 if (i == ARRAY_SIZE(vsp1_routes))
155 return -EINVAL; 158 return -EINVAL;
156 159
157 entity->vsp1 = vsp1; 160 entity->vsp1 = vsp1;
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index f6fd6988aeb0..7afbd8a7ba66 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -20,6 +20,7 @@
20struct vsp1_device; 20struct vsp1_device;
21 21
22enum vsp1_entity_type { 22enum vsp1_entity_type {
23 VSP1_ENTITY_BRU,
23 VSP1_ENTITY_HSI, 24 VSP1_ENTITY_HSI,
24 VSP1_ENTITY_HST, 25 VSP1_ENTITY_HST,
25 VSP1_ENTITY_LIF, 26 VSP1_ENTITY_LIF,
@@ -30,13 +31,31 @@ enum vsp1_entity_type {
30 VSP1_ENTITY_WPF, 31 VSP1_ENTITY_WPF,
31}; 32};
32 33
34/*
35 * struct vsp1_route - Entity routing configuration
36 * @type: Entity type this routing entry is associated with
37 * @index: Entity index this routing entry is associated with
38 * @reg: Output routing configuration register
39 * @inputs: Target node value for each input
40 *
41 * Each $vsp1_route entry describes routing configuration for the entity
42 * specified by the entry's @type and @index. @reg indicates the register that
43 * holds output routing configuration for the entity, and the @inputs array
44 * store the target node value for each input of the entity.
45 */
46struct vsp1_route {
47 enum vsp1_entity_type type;
48 unsigned int index;
49 unsigned int reg;
50 unsigned int inputs[4];
51};
52
33struct vsp1_entity { 53struct vsp1_entity {
34 struct vsp1_device *vsp1; 54 struct vsp1_device *vsp1;
35 55
36 enum vsp1_entity_type type; 56 enum vsp1_entity_type type;
37 unsigned int index; 57 unsigned int index;
38 unsigned int id; 58 const struct vsp1_route *route;
39 unsigned int route;
40 59
41 struct list_head list_dev; 60 struct list_head list_dev;
42 struct list_head list_pipe; 61 struct list_head list_pipe;
@@ -45,6 +64,7 @@ struct vsp1_entity {
45 unsigned int source_pad; 64 unsigned int source_pad;
46 65
47 struct media_entity *sink; 66 struct media_entity *sink;
67 unsigned int sink_pad;
48 68
49 struct v4l2_subdev subdev; 69 struct v4l2_subdev subdev;
50 struct v4l2_mbus_framefmt *formats; 70 struct v4l2_mbus_framefmt *formats;
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 285485350d82..db2950a73c60 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -193,13 +193,10 @@ struct vsp1_hsit *vsp1_hsit_create(struct vsp1_device *vsp1, bool inverse)
193 193
194 hsit->inverse = inverse; 194 hsit->inverse = inverse;
195 195
196 if (inverse) { 196 if (inverse)
197 hsit->entity.type = VSP1_ENTITY_HSI; 197 hsit->entity.type = VSP1_ENTITY_HSI;
198 hsit->entity.id = VI6_DPR_NODE_HSI; 198 else
199 } else {
200 hsit->entity.type = VSP1_ENTITY_HST; 199 hsit->entity.type = VSP1_ENTITY_HST;
201 hsit->entity.id = VI6_DPR_NODE_HST;
202 }
203 200
204 ret = vsp1_entity_init(vsp1, &hsit->entity, 2); 201 ret = vsp1_entity_init(vsp1, &hsit->entity, 2);
205 if (ret < 0) 202 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 135a78957014..d4fb23e9c4a8 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -215,7 +215,6 @@ struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1)
215 return ERR_PTR(-ENOMEM); 215 return ERR_PTR(-ENOMEM);
216 216
217 lif->entity.type = VSP1_ENTITY_LIF; 217 lif->entity.type = VSP1_ENTITY_LIF;
218 lif->entity.id = VI6_DPR_NODE_LIF;
219 218
220 ret = vsp1_entity_init(vsp1, &lif->entity, 2); 219 ret = vsp1_entity_init(vsp1, &lif->entity, 2);
221 if (ret < 0) 220 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 4e9dc7c86ef8..fea36ebe2565 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -229,7 +229,6 @@ struct vsp1_lut *vsp1_lut_create(struct vsp1_device *vsp1)
229 return ERR_PTR(-ENOMEM); 229 return ERR_PTR(-ENOMEM);
230 230
231 lut->entity.type = VSP1_ENTITY_LUT; 231 lut->entity.type = VSP1_ENTITY_LUT;
232 lut->entity.id = VI6_DPR_NODE_LUT;
233 232
234 ret = vsp1_entity_init(vsp1, &lut->entity, 2); 233 ret = vsp1_entity_init(vsp1, &lut->entity, 2);
235 if (ret < 0) 234 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h
index 28650806c20f..3e74b44286f6 100644
--- a/drivers/media/platform/vsp1/vsp1_regs.h
+++ b/drivers/media/platform/vsp1/vsp1_regs.h
@@ -451,13 +451,111 @@
451 * BRU Control Registers 451 * BRU Control Registers
452 */ 452 */
453 453
454#define VI6_ROP_NOP 0
455#define VI6_ROP_AND 1
456#define VI6_ROP_AND_REV 2
457#define VI6_ROP_COPY 3
458#define VI6_ROP_AND_INV 4
459#define VI6_ROP_CLEAR 5
460#define VI6_ROP_XOR 6
461#define VI6_ROP_OR 7
462#define VI6_ROP_NOR 8
463#define VI6_ROP_EQUIV 9
464#define VI6_ROP_INVERT 10
465#define VI6_ROP_OR_REV 11
466#define VI6_ROP_COPY_INV 12
467#define VI6_ROP_OR_INV 13
468#define VI6_ROP_NAND 14
469#define VI6_ROP_SET 15
470
454#define VI6_BRU_INCTRL 0x2c00 471#define VI6_BRU_INCTRL 0x2c00
472#define VI6_BRU_INCTRL_NRM (1 << 28)
473#define VI6_BRU_INCTRL_DnON (1 << (16 + (n)))
474#define VI6_BRU_INCTRL_DITHn_OFF (0 << ((n) * 4))
475#define VI6_BRU_INCTRL_DITHn_18BPP (1 << ((n) * 4))
476#define VI6_BRU_INCTRL_DITHn_16BPP (2 << ((n) * 4))
477#define VI6_BRU_INCTRL_DITHn_15BPP (3 << ((n) * 4))
478#define VI6_BRU_INCTRL_DITHn_12BPP (4 << ((n) * 4))
479#define VI6_BRU_INCTRL_DITHn_8BPP (5 << ((n) * 4))
480#define VI6_BRU_INCTRL_DITHn_MASK (7 << ((n) * 4))
481#define VI6_BRU_INCTRL_DITHn_SHIFT ((n) * 4)
482
455#define VI6_BRU_VIRRPF_SIZE 0x2c04 483#define VI6_BRU_VIRRPF_SIZE 0x2c04
484#define VI6_BRU_VIRRPF_SIZE_HSIZE_MASK (0x1fff << 16)
485#define VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT 16
486#define VI6_BRU_VIRRPF_SIZE_VSIZE_MASK (0x1fff << 0)
487#define VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT 0
488
456#define VI6_BRU_VIRRPF_LOC 0x2c08 489#define VI6_BRU_VIRRPF_LOC 0x2c08
490#define VI6_BRU_VIRRPF_LOC_HCOORD_MASK (0x1fff << 16)
491#define VI6_BRU_VIRRPF_LOC_HCOORD_SHIFT 16
492#define VI6_BRU_VIRRPF_LOC_VCOORD_MASK (0x1fff << 0)
493#define VI6_BRU_VIRRPF_LOC_VCOORD_SHIFT 0
494
457#define VI6_BRU_VIRRPF_COL 0x2c0c 495#define VI6_BRU_VIRRPF_COL 0x2c0c
496#define VI6_BRU_VIRRPF_COL_A_MASK (0xff << 24)
497#define VI6_BRU_VIRRPF_COL_A_SHIFT 24
498#define VI6_BRU_VIRRPF_COL_RCR_MASK (0xff << 16)
499#define VI6_BRU_VIRRPF_COL_RCR_SHIFT 16
500#define VI6_BRU_VIRRPF_COL_GY_MASK (0xff << 8)
501#define VI6_BRU_VIRRPF_COL_GY_SHIFT 8
502#define VI6_BRU_VIRRPF_COL_BCB_MASK (0xff << 0)
503#define VI6_BRU_VIRRPF_COL_BCB_SHIFT 0
504
458#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8) 505#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8)
506#define VI6_BRU_CTRL_RBC (1 << 31)
507#define VI6_BRU_CTRL_DSTSEL_BRUIN(n) ((n) << 20)
508#define VI6_BRU_CTRL_DSTSEL_VRPF (4 << 20)
509#define VI6_BRU_CTRL_DSTSEL_MASK (7 << 20)
510#define VI6_BRU_CTRL_SRCSEL_BRUIN(n) ((n) << 16)
511#define VI6_BRU_CTRL_SRCSEL_VRPF (4 << 16)
512#define VI6_BRU_CTRL_SRCSEL_MASK (7 << 16)
513#define VI6_BRU_CTRL_CROP(rop) ((rop) << 4)
514#define VI6_BRU_CTRL_CROP_MASK (0xf << 4)
515#define VI6_BRU_CTRL_AROP(rop) ((rop) << 0)
516#define VI6_BRU_CTRL_AROP_MASK (0xf << 0)
517
459#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8) 518#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8)
519#define VI6_BRU_BLD_CBES (1 << 31)
520#define VI6_BRU_BLD_CCMDX_DST_A (0 << 28)
521#define VI6_BRU_BLD_CCMDX_255_DST_A (1 << 28)
522#define VI6_BRU_BLD_CCMDX_SRC_A (2 << 28)
523#define VI6_BRU_BLD_CCMDX_255_SRC_A (3 << 28)
524#define VI6_BRU_BLD_CCMDX_COEFX (4 << 28)
525#define VI6_BRU_BLD_CCMDX_MASK (7 << 28)
526#define VI6_BRU_BLD_CCMDY_DST_A (0 << 24)
527#define VI6_BRU_BLD_CCMDY_255_DST_A (1 << 24)
528#define VI6_BRU_BLD_CCMDY_SRC_A (2 << 24)
529#define VI6_BRU_BLD_CCMDY_255_SRC_A (3 << 24)
530#define VI6_BRU_BLD_CCMDY_COEFY (4 << 24)
531#define VI6_BRU_BLD_CCMDY_MASK (7 << 24)
532#define VI6_BRU_BLD_CCMDY_SHIFT 24
533#define VI6_BRU_BLD_ABES (1 << 23)
534#define VI6_BRU_BLD_ACMDX_DST_A (0 << 20)
535#define VI6_BRU_BLD_ACMDX_255_DST_A (1 << 20)
536#define VI6_BRU_BLD_ACMDX_SRC_A (2 << 20)
537#define VI6_BRU_BLD_ACMDX_255_SRC_A (3 << 20)
538#define VI6_BRU_BLD_ACMDX_COEFX (4 << 20)
539#define VI6_BRU_BLD_ACMDX_MASK (7 << 20)
540#define VI6_BRU_BLD_ACMDY_DST_A (0 << 16)
541#define VI6_BRU_BLD_ACMDY_255_DST_A (1 << 16)
542#define VI6_BRU_BLD_ACMDY_SRC_A (2 << 16)
543#define VI6_BRU_BLD_ACMDY_255_SRC_A (3 << 16)
544#define VI6_BRU_BLD_ACMDY_COEFY (4 << 16)
545#define VI6_BRU_BLD_ACMDY_MASK (7 << 16)
546#define VI6_BRU_BLD_COEFX_MASK (0xff << 8)
547#define VI6_BRU_BLD_COEFX_SHIFT 8
548#define VI6_BRU_BLD_COEFY_MASK (0xff << 0)
549#define VI6_BRU_BLD_COEFY_SHIFT 0
550
460#define VI6_BRU_ROP 0x2c30 551#define VI6_BRU_ROP 0x2c30
552#define VI6_BRU_ROP_DSTSEL_BRUIN(n) ((n) << 20)
553#define VI6_BRU_ROP_DSTSEL_VRPF (4 << 20)
554#define VI6_BRU_ROP_DSTSEL_MASK (7 << 20)
555#define VI6_BRU_ROP_CROP(rop) ((rop) << 4)
556#define VI6_BRU_ROP_CROP_MASK (0xf << 4)
557#define VI6_BRU_ROP_AROP(rop) ((rop) << 0)
558#define VI6_BRU_ROP_AROP_MASK (0xf << 0)
461 559
462/* ----------------------------------------------------------------------------- 560/* -----------------------------------------------------------------------------
463 * HGO Control Registers 561 * HGO Control Registers
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 2b04d0f95c62..c3d98642a4aa 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -96,8 +96,10 @@ static int rpf_s_stream(struct v4l2_subdev *subdev, int enable)
96 vsp1_rpf_write(rpf, VI6_RPF_INFMT, infmt); 96 vsp1_rpf_write(rpf, VI6_RPF_INFMT, infmt);
97 vsp1_rpf_write(rpf, VI6_RPF_DSWAP, fmtinfo->swap); 97 vsp1_rpf_write(rpf, VI6_RPF_DSWAP, fmtinfo->swap);
98 98
99 /* Output location. Composing isn't supported yet. */ 99 /* Output location */
100 vsp1_rpf_write(rpf, VI6_RPF_LOC, 0); 100 vsp1_rpf_write(rpf, VI6_RPF_LOC,
101 (rpf->location.left << VI6_RPF_LOC_HCOORD_SHIFT) |
102 (rpf->location.top << VI6_RPF_LOC_VCOORD_SHIFT));
101 103
102 /* Disable alpha, mask and color key. Set the alpha channel to a fixed 104 /* Disable alpha, mask and color key. Set the alpha channel to a fixed
103 * value of 255. 105 * value of 255.
@@ -176,7 +178,6 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
176 178
177 rpf->entity.type = VSP1_ENTITY_RPF; 179 rpf->entity.type = VSP1_ENTITY_RPF;
178 rpf->entity.index = index; 180 rpf->entity.index = index;
179 rpf->entity.id = VI6_DPR_NODE_RPF(index);
180 181
181 ret = vsp1_entity_init(vsp1, &rpf->entity, 2); 182 ret = vsp1_entity_init(vsp1, &rpf->entity, 2);
182 if (ret < 0) 183 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 5c5ee81bbeae..b4fb65e58770 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -30,6 +30,10 @@ struct vsp1_rwpf {
30 unsigned int max_width; 30 unsigned int max_width;
31 unsigned int max_height; 31 unsigned int max_height;
32 32
33 struct {
34 unsigned int left;
35 unsigned int top;
36 } location;
33 struct v4l2_rect crop; 37 struct v4l2_rect crop;
34 38
35 unsigned int offsets[2]; 39 unsigned int offsets[2];
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 7ab1a0b2d656..aa0e04c56f3f 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -327,7 +327,6 @@ struct vsp1_sru *vsp1_sru_create(struct vsp1_device *vsp1)
327 return ERR_PTR(-ENOMEM); 327 return ERR_PTR(-ENOMEM);
328 328
329 sru->entity.type = VSP1_ENTITY_SRU; 329 sru->entity.type = VSP1_ENTITY_SRU;
330 sru->entity.id = VI6_DPR_NODE_SRU;
331 330
332 ret = vsp1_entity_init(vsp1, &sru->entity, 2); 331 ret = vsp1_entity_init(vsp1, &sru->entity, 2);
333 if (ret < 0) 332 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index 622342ac7770..0293bdbb4401 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -131,7 +131,7 @@ static int uds_s_stream(struct v4l2_subdev *subdev, int enable)
131 return 0; 131 return 0;
132 132
133 /* Enable multi-tap scaling. */ 133 /* Enable multi-tap scaling. */
134 vsp1_uds_write(uds, VI6_UDS_CTRL, VI6_UDS_CTRL_BC); 134 vsp1_uds_write(uds, VI6_UDS_CTRL, VI6_UDS_CTRL_AON | VI6_UDS_CTRL_BC);
135 135
136 vsp1_uds_write(uds, VI6_UDS_PASS_BWIDTH, 136 vsp1_uds_write(uds, VI6_UDS_PASS_BWIDTH,
137 (uds_passband_width(uds->hscale) 137 (uds_passband_width(uds->hscale)
@@ -139,7 +139,6 @@ static int uds_s_stream(struct v4l2_subdev *subdev, int enable)
139 (uds_passband_width(uds->vscale) 139 (uds_passband_width(uds->vscale)
140 << VI6_UDS_PASS_BWIDTH_V_SHIFT)); 140 << VI6_UDS_PASS_BWIDTH_V_SHIFT));
141 141
142
143 /* Set the scaling ratios and the output size. */ 142 /* Set the scaling ratios and the output size. */
144 format = &uds->entity.formats[UDS_PAD_SOURCE]; 143 format = &uds->entity.formats[UDS_PAD_SOURCE];
145 144
@@ -323,7 +322,6 @@ struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index)
323 322
324 uds->entity.type = VSP1_ENTITY_UDS; 323 uds->entity.type = VSP1_ENTITY_UDS;
325 uds->entity.index = index; 324 uds->entity.index = index;
326 uds->entity.id = VI6_DPR_NODE_UDS(index);
327 325
328 ret = vsp1_entity_init(vsp1, &uds->entity, 2); 326 ret = vsp1_entity_init(vsp1, &uds->entity, 2);
329 if (ret < 0) 327 if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index a0595c17700f..8a1253e51f04 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -28,6 +28,7 @@
28#include <media/videobuf2-dma-contig.h> 28#include <media/videobuf2-dma-contig.h>
29 29
30#include "vsp1.h" 30#include "vsp1.h"
31#include "vsp1_bru.h"
31#include "vsp1_entity.h" 32#include "vsp1_entity.h"
32#include "vsp1_rwpf.h" 33#include "vsp1_rwpf.h"
33#include "vsp1_video.h" 34#include "vsp1_video.h"
@@ -280,6 +281,9 @@ static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
280 struct media_pad *pad; 281 struct media_pad *pad;
281 bool uds_found = false; 282 bool uds_found = false;
282 283
284 input->location.left = 0;
285 input->location.top = 0;
286
283 pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]); 287 pad = media_entity_remote_pad(&input->entity.pads[RWPF_PAD_SOURCE]);
284 288
285 while (1) { 289 while (1) {
@@ -292,6 +296,17 @@ static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input,
292 296
293 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); 297 entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
294 298
299 /* A BRU is present in the pipeline, store the compose rectangle
300 * location in the input RPF for use when configuring the RPF.
301 */
302 if (entity->type == VSP1_ENTITY_BRU) {
303 struct vsp1_bru *bru = to_bru(&entity->subdev);
304 struct v4l2_rect *rect = &bru->compose[pad->index];
305
306 input->location.left = rect->left;
307 input->location.top = rect->top;
308 }
309
295 /* We've reached the WPF, we're done. */ 310 /* We've reached the WPF, we're done. */
296 if (entity->type == VSP1_ENTITY_WPF) 311 if (entity->type == VSP1_ENTITY_WPF)
297 break; 312 break;
@@ -363,6 +378,8 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
363 rwpf->video.pipe_index = 0; 378 rwpf->video.pipe_index = 0;
364 } else if (e->type == VSP1_ENTITY_LIF) { 379 } else if (e->type == VSP1_ENTITY_LIF) {
365 pipe->lif = e; 380 pipe->lif = e;
381 } else if (e->type == VSP1_ENTITY_BRU) {
382 pipe->bru = e;
366 } 383 }
367 } 384 }
368 385
@@ -392,6 +409,7 @@ error:
392 pipe->num_video = 0; 409 pipe->num_video = 0;
393 pipe->num_inputs = 0; 410 pipe->num_inputs = 0;
394 pipe->output = NULL; 411 pipe->output = NULL;
412 pipe->bru = NULL;
395 pipe->lif = NULL; 413 pipe->lif = NULL;
396 return ret; 414 return ret;
397} 415}
@@ -430,6 +448,7 @@ static void vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe)
430 pipe->num_video = 0; 448 pipe->num_video = 0;
431 pipe->num_inputs = 0; 449 pipe->num_inputs = 0;
432 pipe->output = NULL; 450 pipe->output = NULL;
451 pipe->bru = NULL;
433 pipe->lif = NULL; 452 pipe->lif = NULL;
434 } 453 }
435 454
@@ -461,7 +480,7 @@ static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe)
461 480
462 list_for_each_entry(entity, &pipe->entities, list_pipe) { 481 list_for_each_entry(entity, &pipe->entities, list_pipe) {
463 if (entity->route) 482 if (entity->route)
464 vsp1_write(entity->vsp1, entity->route, 483 vsp1_write(entity->vsp1, entity->route->reg,
465 VI6_DPR_NODE_UNUSED); 484 VI6_DPR_NODE_UNUSED);
466 485
467 v4l2_subdev_call(&entity->subdev, video, s_stream, 0); 486 v4l2_subdev_call(&entity->subdev, video, s_stream, 0);
@@ -680,11 +699,12 @@ static void vsp1_entity_route_setup(struct vsp1_entity *source)
680{ 699{
681 struct vsp1_entity *sink; 700 struct vsp1_entity *sink;
682 701
683 if (source->route == 0) 702 if (source->route->reg == 0)
684 return; 703 return;
685 704
686 sink = container_of(source->sink, struct vsp1_entity, subdev.entity); 705 sink = container_of(source->sink, struct vsp1_entity, subdev.entity);
687 vsp1_write(source->vsp1, source->route, sink->id); 706 vsp1_write(source->vsp1, source->route->reg,
707 sink->route->inputs[source->sink_pad]);
688} 708}
689 709
690static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) 710static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count)
diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h
index 53e4b3745940..c04d48fa2999 100644
--- a/drivers/media/platform/vsp1/vsp1_video.h
+++ b/drivers/media/platform/vsp1/vsp1_video.h
@@ -75,6 +75,7 @@ struct vsp1_pipeline {
75 unsigned int num_inputs; 75 unsigned int num_inputs;
76 struct vsp1_rwpf *inputs[VPS1_MAX_RPF]; 76 struct vsp1_rwpf *inputs[VPS1_MAX_RPF];
77 struct vsp1_rwpf *output; 77 struct vsp1_rwpf *output;
78 struct vsp1_entity *bru;
78 struct vsp1_entity *lif; 79 struct vsp1_entity *lif;
79 80
80 struct list_head entities; 81 struct list_head entities;
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 11a61c601da0..1294340dcb36 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -58,13 +58,21 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable)
58 return 0; 58 return 0;
59 } 59 }
60 60
61 /* Sources */ 61 /* Sources. If the pipeline has a single input configure it as the
62 * master layer. Otherwise configure all inputs as sub-layers and
63 * select the virtual RPF as the master layer.
64 */
62 for (i = 0; i < pipe->num_inputs; ++i) { 65 for (i = 0; i < pipe->num_inputs; ++i) {
63 struct vsp1_rwpf *input = pipe->inputs[i]; 66 struct vsp1_rwpf *input = pipe->inputs[i];
64 67
65 srcrpf |= VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index); 68 srcrpf |= pipe->num_inputs == 1
69 ? VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index)
70 : VI6_WPF_SRCRPF_RPF_ACT_SUB(input->entity.index);
66 } 71 }
67 72
73 if (pipe->num_inputs > 1)
74 srcrpf |= VI6_WPF_SRCRPF_VIRACT_MST;
75
68 vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf); 76 vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf);
69 77
70 /* Destination stride. */ 78 /* Destination stride. */
@@ -181,7 +189,6 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
181 189
182 wpf->entity.type = VSP1_ENTITY_WPF; 190 wpf->entity.type = VSP1_ENTITY_WPF;
183 wpf->entity.index = index; 191 wpf->entity.index = index;
184 wpf->entity.id = VI6_DPR_NODE_WPF(index);
185 192
186 ret = vsp1_entity_init(vsp1, &wpf->entity, 2); 193 ret = vsp1_entity_init(vsp1, &wpf->entity, 2);
187 if (ret < 0) 194 if (ret < 0)
diff --git a/include/media/adv7604.h b/include/media/adv7604.h
index c6b39372eed7..aa1c4477722d 100644
--- a/include/media/adv7604.h
+++ b/include/media/adv7604.h
@@ -32,14 +32,18 @@ enum adv7604_ain_sel {
32 ADV7604_AIN9_4_5_6_SYNC_2_1 = 4, 32 ADV7604_AIN9_4_5_6_SYNC_2_1 = 4,
33}; 33};
34 34
35/* Bus rotation and reordering (IO register 0x04, [7:5]) */ 35/*
36enum adv7604_op_ch_sel { 36 * Bus rotation and reordering. This is used to specify component reordering on
37 ADV7604_OP_CH_SEL_GBR = 0, 37 * the board and describes the components order on the bus when the ADV7604
38 ADV7604_OP_CH_SEL_GRB = 1, 38 * outputs RGB.
39 ADV7604_OP_CH_SEL_BGR = 2, 39 */
40 ADV7604_OP_CH_SEL_RGB = 3, 40enum adv7604_bus_order {
41 ADV7604_OP_CH_SEL_BRG = 4, 41 ADV7604_BUS_ORDER_RGB, /* No operation */
42 ADV7604_OP_CH_SEL_RBG = 5, 42 ADV7604_BUS_ORDER_GRB, /* Swap 1-2 */
43 ADV7604_BUS_ORDER_RBG, /* Swap 2-3 */
44 ADV7604_BUS_ORDER_BGR, /* Swap 1-3 */
45 ADV7604_BUS_ORDER_BRG, /* Rotate right */
46 ADV7604_BUS_ORDER_GBR, /* Rotate left */
43}; 47};
44 48
45/* Input Color Space (IO register 0x02, [7:4]) */ 49/* Input Color Space (IO register 0x02, [7:4]) */
@@ -55,29 +59,11 @@ enum adv7604_inp_color_space {
55 ADV7604_INP_COLOR_SPACE_AUTO = 0xf, 59 ADV7604_INP_COLOR_SPACE_AUTO = 0xf,
56}; 60};
57 61
58/* Select output format (IO register 0x03, [7:0]) */ 62/* Select output format (IO register 0x03, [4:2]) */
59enum adv7604_op_format_sel { 63enum adv7604_op_format_mode_sel {
60 ADV7604_OP_FORMAT_SEL_SDR_ITU656_8 = 0x00, 64 ADV7604_OP_FORMAT_MODE0 = 0x00,
61 ADV7604_OP_FORMAT_SEL_SDR_ITU656_10 = 0x01, 65 ADV7604_OP_FORMAT_MODE1 = 0x04,
62 ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE0 = 0x02, 66 ADV7604_OP_FORMAT_MODE2 = 0x08,
63 ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE1 = 0x06,
64 ADV7604_OP_FORMAT_SEL_SDR_ITU656_12_MODE2 = 0x0a,
65 ADV7604_OP_FORMAT_SEL_DDR_422_8 = 0x20,
66 ADV7604_OP_FORMAT_SEL_DDR_422_10 = 0x21,
67 ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE0 = 0x22,
68 ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE1 = 0x23,
69 ADV7604_OP_FORMAT_SEL_DDR_422_12_MODE2 = 0x24,
70 ADV7604_OP_FORMAT_SEL_SDR_444_24 = 0x40,
71 ADV7604_OP_FORMAT_SEL_SDR_444_30 = 0x41,
72 ADV7604_OP_FORMAT_SEL_SDR_444_36_MODE0 = 0x42,
73 ADV7604_OP_FORMAT_SEL_DDR_444_24 = 0x60,
74 ADV7604_OP_FORMAT_SEL_DDR_444_30 = 0x61,
75 ADV7604_OP_FORMAT_SEL_DDR_444_36 = 0x62,
76 ADV7604_OP_FORMAT_SEL_SDR_ITU656_16 = 0x80,
77 ADV7604_OP_FORMAT_SEL_SDR_ITU656_20 = 0x81,
78 ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE0 = 0x82,
79 ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE1 = 0x86,
80 ADV7604_OP_FORMAT_SEL_SDR_ITU656_24_MODE2 = 0x8a,
81}; 67};
82 68
83enum adv7604_drive_strength { 69enum adv7604_drive_strength {
@@ -86,6 +72,30 @@ enum adv7604_drive_strength {
86 ADV7604_DR_STR_HIGH = 3, 72 ADV7604_DR_STR_HIGH = 3,
87}; 73};
88 74
75enum adv7604_int1_config {
76 ADV7604_INT1_CONFIG_OPEN_DRAIN,
77 ADV7604_INT1_CONFIG_ACTIVE_LOW,
78 ADV7604_INT1_CONFIG_ACTIVE_HIGH,
79 ADV7604_INT1_CONFIG_DISABLED,
80};
81
82enum adv7604_page {
83 ADV7604_PAGE_IO,
84 ADV7604_PAGE_AVLINK,
85 ADV7604_PAGE_CEC,
86 ADV7604_PAGE_INFOFRAME,
87 ADV7604_PAGE_ESDP,
88 ADV7604_PAGE_DPP,
89 ADV7604_PAGE_AFE,
90 ADV7604_PAGE_REP,
91 ADV7604_PAGE_EDID,
92 ADV7604_PAGE_HDMI,
93 ADV7604_PAGE_TEST,
94 ADV7604_PAGE_CP,
95 ADV7604_PAGE_VDP,
96 ADV7604_PAGE_MAX,
97};
98
89/* Platform dependent definition */ 99/* Platform dependent definition */
90struct adv7604_platform_data { 100struct adv7604_platform_data {
91 /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */ 101 /* DIS_PWRDNB: 1 if the PWRDNB pin is unused and unconnected */
@@ -94,30 +104,34 @@ struct adv7604_platform_data {
94 /* DIS_CABLE_DET_RST: 1 if the 5V pins are unused and unconnected */ 104 /* DIS_CABLE_DET_RST: 1 if the 5V pins are unused and unconnected */
95 unsigned disable_cable_det_rst:1; 105 unsigned disable_cable_det_rst:1;
96 106
107 int default_input;
108
97 /* Analog input muxing mode */ 109 /* Analog input muxing mode */
98 enum adv7604_ain_sel ain_sel; 110 enum adv7604_ain_sel ain_sel;
99 111
100 /* Bus rotation and reordering */ 112 /* Bus rotation and reordering */
101 enum adv7604_op_ch_sel op_ch_sel; 113 enum adv7604_bus_order bus_order;
102 114
103 /* Select output format */ 115 /* Select output format mode */
104 enum adv7604_op_format_sel op_format_sel; 116 enum adv7604_op_format_mode_sel op_format_mode_sel;
117
118 /* Configuration of the INT1 pin */
119 enum adv7604_int1_config int1_config;
105 120
106 /* IO register 0x02 */ 121 /* IO register 0x02 */
107 unsigned alt_gamma:1; 122 unsigned alt_gamma:1;
108 unsigned op_656_range:1; 123 unsigned op_656_range:1;
109 unsigned rgb_out:1;
110 unsigned alt_data_sat:1; 124 unsigned alt_data_sat:1;
111 125
112 /* IO register 0x05 */ 126 /* IO register 0x05 */
113 unsigned blank_data:1; 127 unsigned blank_data:1;
114 unsigned insert_av_codes:1; 128 unsigned insert_av_codes:1;
115 unsigned replicate_av_codes:1; 129 unsigned replicate_av_codes:1;
116 unsigned invert_cbcr:1;
117 130
118 /* IO register 0x06 */ 131 /* IO register 0x06 */
119 unsigned inv_vs_pol:1; 132 unsigned inv_vs_pol:1;
120 unsigned inv_hs_pol:1; 133 unsigned inv_hs_pol:1;
134 unsigned inv_llc_pol:1;
121 135
122 /* IO register 0x14 */ 136 /* IO register 0x14 */
123 enum adv7604_drive_strength dr_str_data; 137 enum adv7604_drive_strength dr_str_data;
@@ -131,34 +145,22 @@ struct adv7604_platform_data {
131 unsigned hdmi_free_run_mode; 145 unsigned hdmi_free_run_mode;
132 146
133 /* i2c addresses: 0 == use default */ 147 /* i2c addresses: 0 == use default */
134 u8 i2c_avlink; 148 u8 i2c_addresses[ADV7604_PAGE_MAX];
135 u8 i2c_cec;
136 u8 i2c_infoframe;
137 u8 i2c_esdp;
138 u8 i2c_dpp;
139 u8 i2c_afe;
140 u8 i2c_repeater;
141 u8 i2c_edid;
142 u8 i2c_hdmi;
143 u8 i2c_test;
144 u8 i2c_cp;
145 u8 i2c_vdp;
146}; 149};
147 150
148enum adv7604_input_port { 151enum adv7604_pad {
149 ADV7604_INPUT_HDMI_PORT_A, 152 ADV7604_PAD_HDMI_PORT_A = 0,
150 ADV7604_INPUT_HDMI_PORT_B, 153 ADV7604_PAD_HDMI_PORT_B = 1,
151 ADV7604_INPUT_HDMI_PORT_C, 154 ADV7604_PAD_HDMI_PORT_C = 2,
152 ADV7604_INPUT_HDMI_PORT_D, 155 ADV7604_PAD_HDMI_PORT_D = 3,
153 ADV7604_INPUT_VGA_RGB, 156 ADV7604_PAD_VGA_RGB = 4,
154 ADV7604_INPUT_VGA_COMP, 157 ADV7604_PAD_VGA_COMP = 5,
158 /* The source pad is either 1 (ADV7611) or 6 (ADV7604) */
159 ADV7604_PAD_SOURCE = 6,
160 ADV7611_PAD_SOURCE = 1,
161 ADV7604_PAD_MAX = 7,
155}; 162};
156 163
157#define ADV7604_EDID_PORT_A 0
158#define ADV7604_EDID_PORT_B 1
159#define ADV7604_EDID_PORT_C 2
160#define ADV7604_EDID_PORT_D 3
161
162#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) 164#define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000)
163#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) 165#define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001)
164#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) 166#define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002)
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 9fab013eea86..d7465725773d 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -338,12 +338,8 @@ struct v4l2_subdev_video_ops {
338 struct v4l2_dv_timings *timings); 338 struct v4l2_dv_timings *timings);
339 int (*g_dv_timings)(struct v4l2_subdev *sd, 339 int (*g_dv_timings)(struct v4l2_subdev *sd,
340 struct v4l2_dv_timings *timings); 340 struct v4l2_dv_timings *timings);
341 int (*enum_dv_timings)(struct v4l2_subdev *sd,
342 struct v4l2_enum_dv_timings *timings);
343 int (*query_dv_timings)(struct v4l2_subdev *sd, 341 int (*query_dv_timings)(struct v4l2_subdev *sd,
344 struct v4l2_dv_timings *timings); 342 struct v4l2_dv_timings *timings);
345 int (*dv_timings_cap)(struct v4l2_subdev *sd,
346 struct v4l2_dv_timings_cap *cap);
347 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, 343 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
348 enum v4l2_mbus_pixelcode *code); 344 enum v4l2_mbus_pixelcode *code);
349 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, 345 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,