.. | .. |
---|
10 | 10 | #include <linux/videodev2.h> |
---|
11 | 11 | #include <linux/delay.h> |
---|
12 | 12 | #include <linux/gpio/consumer.h> |
---|
| 13 | +#include <linux/interrupt.h> |
---|
13 | 14 | #include <linux/module.h> |
---|
14 | 15 | #include <linux/of_graph.h> |
---|
| 16 | +#include <linux/pm_runtime.h> |
---|
| 17 | +#include <linux/regmap.h> |
---|
15 | 18 | #include <media/v4l2-async.h> |
---|
16 | 19 | #include <media/v4l2-device.h> |
---|
| 20 | +#include <media/v4l2-event.h> |
---|
17 | 21 | #include <media/v4l2-ctrls.h> |
---|
18 | 22 | #include <media/v4l2-fwnode.h> |
---|
19 | 23 | #include <media/v4l2-mc.h> |
---|
| 24 | +#include <media/v4l2-rect.h> |
---|
20 | 25 | |
---|
21 | 26 | #include "tvp5150_reg.h" |
---|
22 | 27 | |
---|
.. | .. |
---|
26 | 31 | #define TVP5150_MAX_CROP_LEFT 511 |
---|
27 | 32 | #define TVP5150_MAX_CROP_TOP 127 |
---|
28 | 33 | #define TVP5150_CROP_SHIFT 2 |
---|
| 34 | +#define TVP5150_MBUS_FMT MEDIA_BUS_FMT_UYVY8_2X8 |
---|
| 35 | +#define TVP5150_FIELD V4L2_FIELD_ALTERNATE |
---|
| 36 | +#define TVP5150_COLORSPACE V4L2_COLORSPACE_SMPTE170M |
---|
| 37 | +#define TVP5150_STD_MASK (V4L2_STD_NTSC | \ |
---|
| 38 | + V4L2_STD_NTSC_443 | \ |
---|
| 39 | + V4L2_STD_PAL | \ |
---|
| 40 | + V4L2_STD_PAL_M | \ |
---|
| 41 | + V4L2_STD_PAL_N | \ |
---|
| 42 | + V4L2_STD_PAL_Nc | \ |
---|
| 43 | + V4L2_STD_SECAM) |
---|
| 44 | + |
---|
| 45 | +#define TVP5150_MAX_CONNECTORS 3 /* Check dt-bindings for more information */ |
---|
29 | 46 | |
---|
30 | 47 | MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver"); |
---|
31 | 48 | MODULE_AUTHOR("Mauro Carvalho Chehab"); |
---|
.. | .. |
---|
38 | 55 | |
---|
39 | 56 | #define dprintk0(__dev, __arg...) dev_dbg_lvl(__dev, 0, 0, __arg) |
---|
40 | 57 | |
---|
| 58 | +enum tvp5150_pads { |
---|
| 59 | + TVP5150_PAD_AIP1A, |
---|
| 60 | + TVP5150_PAD_AIP1B, |
---|
| 61 | + TVP5150_PAD_VID_OUT, |
---|
| 62 | + TVP5150_NUM_PADS |
---|
| 63 | +}; |
---|
| 64 | + |
---|
| 65 | +struct tvp5150_connector { |
---|
| 66 | + struct v4l2_fwnode_connector base; |
---|
| 67 | + struct media_entity ent; |
---|
| 68 | + struct media_pad pad; |
---|
| 69 | +}; |
---|
| 70 | + |
---|
41 | 71 | struct tvp5150 { |
---|
42 | 72 | struct v4l2_subdev sd; |
---|
43 | | -#ifdef CONFIG_MEDIA_CONTROLLER |
---|
44 | | - struct media_pad pads[DEMOD_NUM_PADS]; |
---|
45 | | - struct media_entity input_ent[TVP5150_INPUT_NUM]; |
---|
46 | | - struct media_pad input_pad[TVP5150_INPUT_NUM]; |
---|
47 | | -#endif |
---|
| 73 | + |
---|
| 74 | + struct media_pad pads[TVP5150_NUM_PADS]; |
---|
| 75 | + struct tvp5150_connector connectors[TVP5150_MAX_CONNECTORS]; |
---|
| 76 | + struct tvp5150_connector *cur_connector; |
---|
| 77 | + unsigned int connectors_num; |
---|
| 78 | + |
---|
48 | 79 | struct v4l2_ctrl_handler hdl; |
---|
49 | 80 | struct v4l2_rect rect; |
---|
| 81 | + struct regmap *regmap; |
---|
| 82 | + int irq; |
---|
50 | 83 | |
---|
51 | 84 | v4l2_std_id norm; /* Current set standard */ |
---|
| 85 | + v4l2_std_id detected_norm; |
---|
52 | 86 | u32 input; |
---|
53 | 87 | u32 output; |
---|
| 88 | + u32 oe; |
---|
54 | 89 | int enable; |
---|
| 90 | + bool lock; |
---|
55 | 91 | |
---|
56 | 92 | u16 dev_id; |
---|
57 | 93 | u16 rom_ver; |
---|
.. | .. |
---|
71 | 107 | |
---|
72 | 108 | static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) |
---|
73 | 109 | { |
---|
74 | | - struct i2c_client *c = v4l2_get_subdevdata(sd); |
---|
75 | | - int rc; |
---|
| 110 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 111 | + int ret, val; |
---|
76 | 112 | |
---|
77 | | - rc = i2c_smbus_read_byte_data(c, addr); |
---|
78 | | - if (rc < 0) { |
---|
79 | | - dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc); |
---|
80 | | - return rc; |
---|
81 | | - } |
---|
| 113 | + ret = regmap_read(decoder->regmap, addr, &val); |
---|
| 114 | + if (ret < 0) |
---|
| 115 | + return ret; |
---|
82 | 116 | |
---|
83 | | - dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: read 0x%02x = %02x\n", addr, rc); |
---|
84 | | - |
---|
85 | | - return rc; |
---|
86 | | -} |
---|
87 | | - |
---|
88 | | -static int tvp5150_write(struct v4l2_subdev *sd, unsigned char addr, |
---|
89 | | - unsigned char value) |
---|
90 | | -{ |
---|
91 | | - struct i2c_client *c = v4l2_get_subdevdata(sd); |
---|
92 | | - int rc; |
---|
93 | | - |
---|
94 | | - dev_dbg_lvl(sd->dev, 2, debug, "tvp5150: writing %02x %02x\n", addr, value); |
---|
95 | | - rc = i2c_smbus_write_byte_data(c, addr, value); |
---|
96 | | - if (rc < 0) |
---|
97 | | - dev_err(sd->dev, "i2c i/o error: rc == %d\n", rc); |
---|
98 | | - |
---|
99 | | - return rc; |
---|
| 117 | + return val; |
---|
100 | 118 | } |
---|
101 | 119 | |
---|
102 | 120 | static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init, |
---|
.. | .. |
---|
262 | 280 | { |
---|
263 | 281 | int opmode = 0; |
---|
264 | 282 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 283 | + unsigned int mask, val; |
---|
265 | 284 | int input = 0; |
---|
266 | | - int val; |
---|
267 | 285 | |
---|
268 | 286 | /* Only tvp5150am1 and tvp5151 have signal generator support */ |
---|
269 | 287 | if ((decoder->dev_id == 0x5150 && decoder->rom_ver == 0x0400) || |
---|
.. | .. |
---|
275 | 293 | switch (decoder->input) { |
---|
276 | 294 | case TVP5150_COMPOSITE1: |
---|
277 | 295 | input |= 2; |
---|
278 | | - /* fall through */ |
---|
| 296 | + fallthrough; |
---|
279 | 297 | case TVP5150_COMPOSITE0: |
---|
280 | 298 | break; |
---|
281 | 299 | case TVP5150_SVIDEO: |
---|
.. | .. |
---|
284 | 302 | break; |
---|
285 | 303 | } |
---|
286 | 304 | |
---|
287 | | - dev_dbg_lvl(sd->dev, 1, debug, "Selecting video route: route input=%i, output=%i => tvp5150 input=%i, opmode=%i\n", |
---|
288 | | - decoder->input, decoder->output, |
---|
289 | | - input, opmode); |
---|
| 305 | + dev_dbg_lvl(sd->dev, 1, debug, |
---|
| 306 | + "Selecting video route: route input=%s, output=%s => tvp5150 input=0x%02x, opmode=0x%02x\n", |
---|
| 307 | + decoder->input == 0 ? "aip1a" : |
---|
| 308 | + decoder->input == 2 ? "aip1b" : "svideo", |
---|
| 309 | + decoder->output == 0 ? "normal" : "black-frame-gen", |
---|
| 310 | + input, opmode); |
---|
290 | 311 | |
---|
291 | | - tvp5150_write(sd, TVP5150_OP_MODE_CTL, opmode); |
---|
292 | | - tvp5150_write(sd, TVP5150_VD_IN_SRC_SEL_1, input); |
---|
| 312 | + regmap_write(decoder->regmap, TVP5150_OP_MODE_CTL, opmode); |
---|
| 313 | + regmap_write(decoder->regmap, TVP5150_VD_IN_SRC_SEL_1, input); |
---|
293 | 314 | |
---|
294 | 315 | /* |
---|
295 | 316 | * Setup the FID/GLCO/VLK/HVLK and INTREQ/GPCL/VBLK output signals. For |
---|
.. | .. |
---|
298 | 319 | * field indicator (FID) signal on FID/GLCO/VLK/HVLK and set |
---|
299 | 320 | * INTREQ/GPCL/VBLK to logic 1. |
---|
300 | 321 | */ |
---|
301 | | - val = tvp5150_read(sd, TVP5150_MISC_CTL); |
---|
302 | | - if (val < 0) { |
---|
303 | | - dev_err(sd->dev, "%s: failed with error = %d\n", __func__, val); |
---|
304 | | - return; |
---|
305 | | - } |
---|
306 | | - |
---|
| 322 | + mask = TVP5150_MISC_CTL_GPCL | TVP5150_MISC_CTL_HVLK; |
---|
307 | 323 | if (decoder->input == TVP5150_SVIDEO) |
---|
308 | | - val = (val & ~TVP5150_MISC_CTL_GPCL) | TVP5150_MISC_CTL_HVLK; |
---|
| 324 | + val = TVP5150_MISC_CTL_HVLK; |
---|
309 | 325 | else |
---|
310 | | - val = (val & ~TVP5150_MISC_CTL_HVLK) | TVP5150_MISC_CTL_GPCL; |
---|
311 | | - tvp5150_write(sd, TVP5150_MISC_CTL, val); |
---|
| 326 | + val = TVP5150_MISC_CTL_GPCL; |
---|
| 327 | + regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val); |
---|
312 | 328 | }; |
---|
313 | 329 | |
---|
314 | 330 | struct i2c_reg_value { |
---|
.. | .. |
---|
454 | 470 | |
---|
455 | 471 | /* Default values as sugested at TVP5150AM1 datasheet */ |
---|
456 | 472 | static const struct i2c_reg_value tvp5150_init_enable[] = { |
---|
457 | | - { |
---|
458 | | - TVP5150_CONF_SHARED_PIN, 2 |
---|
459 | | - }, { /* Automatic offset and AGC enabled */ |
---|
| 473 | + { /* Automatic offset and AGC enabled */ |
---|
460 | 474 | TVP5150_ANAL_CHL_CTL, 0x15 |
---|
461 | 475 | }, { /* Activate YCrCb output 0x9 or 0xd ? */ |
---|
462 | 476 | TVP5150_MISC_CTL, TVP5150_MISC_CTL_GPCL | |
---|
.. | .. |
---|
583 | 597 | static int tvp5150_write_inittab(struct v4l2_subdev *sd, |
---|
584 | 598 | const struct i2c_reg_value *regs) |
---|
585 | 599 | { |
---|
| 600 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 601 | + |
---|
586 | 602 | while (regs->reg != 0xff) { |
---|
587 | | - tvp5150_write(sd, regs->reg, regs->value); |
---|
| 603 | + regmap_write(decoder->regmap, regs->reg, regs->value); |
---|
588 | 604 | regs++; |
---|
589 | 605 | } |
---|
590 | 606 | return 0; |
---|
.. | .. |
---|
592 | 608 | |
---|
593 | 609 | static int tvp5150_vdp_init(struct v4l2_subdev *sd) |
---|
594 | 610 | { |
---|
| 611 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 612 | + struct regmap *map = decoder->regmap; |
---|
595 | 613 | unsigned int i; |
---|
596 | 614 | int j; |
---|
597 | 615 | |
---|
598 | 616 | /* Disable Full Field */ |
---|
599 | | - tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); |
---|
| 617 | + regmap_write(map, TVP5150_FULL_FIELD_ENA, 0); |
---|
600 | 618 | |
---|
601 | 619 | /* Before programming, Line mode should be at 0xff */ |
---|
602 | 620 | for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++) |
---|
603 | | - tvp5150_write(sd, i, 0xff); |
---|
| 621 | + regmap_write(map, i, 0xff); |
---|
604 | 622 | |
---|
605 | 623 | /* Load Ram Table */ |
---|
606 | 624 | for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) { |
---|
.. | .. |
---|
609 | 627 | if (!regs->type.vbi_type) |
---|
610 | 628 | continue; |
---|
611 | 629 | |
---|
612 | | - tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); |
---|
613 | | - tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); |
---|
| 630 | + regmap_write(map, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); |
---|
| 631 | + regmap_write(map, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); |
---|
614 | 632 | |
---|
615 | 633 | for (i = 0; i < 16; i++) |
---|
616 | | - tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); |
---|
| 634 | + regmap_write(map, TVP5150_VDP_CONF_RAM_DATA, |
---|
| 635 | + regs->values[i]); |
---|
617 | 636 | } |
---|
618 | 637 | return 0; |
---|
619 | 638 | } |
---|
.. | .. |
---|
693 | 712 | reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; |
---|
694 | 713 | |
---|
695 | 714 | if (fields & 1) |
---|
696 | | - tvp5150_write(sd, reg, type); |
---|
| 715 | + regmap_write(decoder->regmap, reg, type); |
---|
697 | 716 | |
---|
698 | 717 | if (fields & 2) |
---|
699 | | - tvp5150_write(sd, reg + 1, type); |
---|
| 718 | + regmap_write(decoder->regmap, reg + 1, type); |
---|
700 | 719 | |
---|
701 | 720 | return type; |
---|
702 | 721 | } |
---|
.. | .. |
---|
742 | 761 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
743 | 762 | int fmt = 0; |
---|
744 | 763 | |
---|
745 | | - decoder->norm = std; |
---|
746 | | - |
---|
747 | 764 | /* First tests should be against specific std */ |
---|
748 | 765 | |
---|
749 | 766 | if (std == V4L2_STD_NTSC_443) { |
---|
.. | .. |
---|
763 | 780 | } |
---|
764 | 781 | |
---|
765 | 782 | dev_dbg_lvl(sd->dev, 1, debug, "Set video std register to %d.\n", fmt); |
---|
766 | | - tvp5150_write(sd, TVP5150_VIDEO_STD, fmt); |
---|
| 783 | + regmap_write(decoder->regmap, TVP5150_VIDEO_STD, fmt); |
---|
| 784 | + return 0; |
---|
| 785 | +} |
---|
| 786 | + |
---|
| 787 | +static int tvp5150_g_std(struct v4l2_subdev *sd, v4l2_std_id *std) |
---|
| 788 | +{ |
---|
| 789 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 790 | + |
---|
| 791 | + *std = decoder->norm; |
---|
| 792 | + |
---|
767 | 793 | return 0; |
---|
768 | 794 | } |
---|
769 | 795 | |
---|
770 | 796 | static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std) |
---|
771 | 797 | { |
---|
772 | 798 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 799 | + struct tvp5150_connector *cur_con = decoder->cur_connector; |
---|
| 800 | + v4l2_std_id supported_stds; |
---|
773 | 801 | |
---|
774 | 802 | if (decoder->norm == std) |
---|
775 | 803 | return 0; |
---|
| 804 | + |
---|
| 805 | + /* In case of no of-connectors are available no limitations are made */ |
---|
| 806 | + if (!decoder->connectors_num) |
---|
| 807 | + supported_stds = V4L2_STD_ALL; |
---|
| 808 | + else |
---|
| 809 | + supported_stds = cur_con->base.connector.analog.sdtv_stds; |
---|
| 810 | + |
---|
| 811 | + /* |
---|
| 812 | + * Check if requested std or group of std's is/are supported by the |
---|
| 813 | + * connector. |
---|
| 814 | + */ |
---|
| 815 | + if ((supported_stds & std) == 0) |
---|
| 816 | + return -EINVAL; |
---|
776 | 817 | |
---|
777 | 818 | /* Change cropping height limits */ |
---|
778 | 819 | if (std & V4L2_STD_525_60) |
---|
.. | .. |
---|
780 | 821 | else |
---|
781 | 822 | decoder->rect.height = TVP5150_V_MAX_OTHERS; |
---|
782 | 823 | |
---|
| 824 | + /* Set only the specific supported std in case of group of std's. */ |
---|
| 825 | + decoder->norm = supported_stds & std; |
---|
783 | 826 | |
---|
784 | 827 | return tvp5150_set_std(sd, std); |
---|
785 | | -} |
---|
786 | | - |
---|
787 | | -static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) |
---|
788 | | -{ |
---|
789 | | - struct tvp5150 *decoder = to_tvp5150(sd); |
---|
790 | | - |
---|
791 | | - /* Initializes TVP5150 to its default values */ |
---|
792 | | - tvp5150_write_inittab(sd, tvp5150_init_default); |
---|
793 | | - |
---|
794 | | - /* Initializes VDP registers */ |
---|
795 | | - tvp5150_vdp_init(sd); |
---|
796 | | - |
---|
797 | | - /* Selects decoder input */ |
---|
798 | | - tvp5150_selmux(sd); |
---|
799 | | - |
---|
800 | | - /* Initializes TVP5150 to stream enabled values */ |
---|
801 | | - tvp5150_write_inittab(sd, tvp5150_init_enable); |
---|
802 | | - |
---|
803 | | - /* Initialize image preferences */ |
---|
804 | | - v4l2_ctrl_handler_setup(&decoder->hdl); |
---|
805 | | - |
---|
806 | | - tvp5150_set_std(sd, decoder->norm); |
---|
807 | | - |
---|
808 | | - if (decoder->mbus_type == V4L2_MBUS_PARALLEL) |
---|
809 | | - tvp5150_write(sd, TVP5150_DATA_RATE_SEL, 0x40); |
---|
810 | | - |
---|
811 | | - return 0; |
---|
812 | | -}; |
---|
813 | | - |
---|
814 | | -static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl) |
---|
815 | | -{ |
---|
816 | | - struct v4l2_subdev *sd = to_sd(ctrl); |
---|
817 | | - struct tvp5150 *decoder = to_tvp5150(sd); |
---|
818 | | - |
---|
819 | | - switch (ctrl->id) { |
---|
820 | | - case V4L2_CID_BRIGHTNESS: |
---|
821 | | - tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val); |
---|
822 | | - return 0; |
---|
823 | | - case V4L2_CID_CONTRAST: |
---|
824 | | - tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val); |
---|
825 | | - return 0; |
---|
826 | | - case V4L2_CID_SATURATION: |
---|
827 | | - tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val); |
---|
828 | | - return 0; |
---|
829 | | - case V4L2_CID_HUE: |
---|
830 | | - tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val); |
---|
831 | | - return 0; |
---|
832 | | - case V4L2_CID_TEST_PATTERN: |
---|
833 | | - decoder->enable = ctrl->val ? false : true; |
---|
834 | | - tvp5150_selmux(sd); |
---|
835 | | - return 0; |
---|
836 | | - } |
---|
837 | | - return -EINVAL; |
---|
838 | 828 | } |
---|
839 | 829 | |
---|
840 | 830 | static v4l2_std_id tvp5150_read_std(struct v4l2_subdev *sd) |
---|
.. | .. |
---|
859 | 849 | } |
---|
860 | 850 | } |
---|
861 | 851 | |
---|
| 852 | +static int query_lock(struct v4l2_subdev *sd) |
---|
| 853 | +{ |
---|
| 854 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 855 | + int status; |
---|
| 856 | + |
---|
| 857 | + if (decoder->irq) |
---|
| 858 | + return decoder->lock; |
---|
| 859 | + |
---|
| 860 | + regmap_read(decoder->regmap, TVP5150_STATUS_REG_1, &status); |
---|
| 861 | + |
---|
| 862 | + /* For standard detection, we need the 3 locks */ |
---|
| 863 | + return (status & 0x0e) == 0x0e; |
---|
| 864 | +} |
---|
| 865 | + |
---|
| 866 | +static int tvp5150_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id) |
---|
| 867 | +{ |
---|
| 868 | + *std_id = query_lock(sd) ? tvp5150_read_std(sd) : V4L2_STD_UNKNOWN; |
---|
| 869 | + |
---|
| 870 | + return 0; |
---|
| 871 | +} |
---|
| 872 | + |
---|
| 873 | +static const struct v4l2_event tvp5150_ev_fmt = { |
---|
| 874 | + .type = V4L2_EVENT_SOURCE_CHANGE, |
---|
| 875 | + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, |
---|
| 876 | +}; |
---|
| 877 | + |
---|
| 878 | +static irqreturn_t tvp5150_isr(int irq, void *dev_id) |
---|
| 879 | +{ |
---|
| 880 | + struct tvp5150 *decoder = dev_id; |
---|
| 881 | + struct regmap *map = decoder->regmap; |
---|
| 882 | + unsigned int mask, active = 0, status = 0; |
---|
| 883 | + |
---|
| 884 | + mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE | |
---|
| 885 | + TVP5150_MISC_CTL_CLOCK_OE; |
---|
| 886 | + |
---|
| 887 | + regmap_read(map, TVP5150_INT_STATUS_REG_A, &status); |
---|
| 888 | + if (status) { |
---|
| 889 | + regmap_write(map, TVP5150_INT_STATUS_REG_A, status); |
---|
| 890 | + |
---|
| 891 | + if (status & TVP5150_INT_A_LOCK) { |
---|
| 892 | + decoder->lock = !!(status & TVP5150_INT_A_LOCK_STATUS); |
---|
| 893 | + dev_dbg_lvl(decoder->sd.dev, 1, debug, |
---|
| 894 | + "sync lo%s signal\n", |
---|
| 895 | + decoder->lock ? "ck" : "ss"); |
---|
| 896 | + v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt); |
---|
| 897 | + regmap_update_bits(map, TVP5150_MISC_CTL, mask, |
---|
| 898 | + decoder->lock ? decoder->oe : 0); |
---|
| 899 | + } |
---|
| 900 | + |
---|
| 901 | + return IRQ_HANDLED; |
---|
| 902 | + } |
---|
| 903 | + |
---|
| 904 | + regmap_read(map, TVP5150_INT_ACTIVE_REG_B, &active); |
---|
| 905 | + if (active) { |
---|
| 906 | + status = 0; |
---|
| 907 | + regmap_read(map, TVP5150_INT_STATUS_REG_B, &status); |
---|
| 908 | + if (status) |
---|
| 909 | + regmap_write(map, TVP5150_INT_RESET_REG_B, status); |
---|
| 910 | + } |
---|
| 911 | + |
---|
| 912 | + return IRQ_HANDLED; |
---|
| 913 | +} |
---|
| 914 | + |
---|
| 915 | +static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) |
---|
| 916 | +{ |
---|
| 917 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 918 | + struct regmap *map = decoder->regmap; |
---|
| 919 | + |
---|
| 920 | + /* Initializes TVP5150 to its default values */ |
---|
| 921 | + tvp5150_write_inittab(sd, tvp5150_init_default); |
---|
| 922 | + |
---|
| 923 | + if (decoder->irq) { |
---|
| 924 | + /* Configure pins: FID, VSYNC, INTREQ, SCLK */ |
---|
| 925 | + regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x0); |
---|
| 926 | + /* Set interrupt polarity to active high */ |
---|
| 927 | + regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE | 0x1); |
---|
| 928 | + regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x1); |
---|
| 929 | + } else { |
---|
| 930 | + /* Configure pins: FID, VSYNC, GPCL/VBLK, SCLK */ |
---|
| 931 | + regmap_write(map, TVP5150_CONF_SHARED_PIN, 0x2); |
---|
| 932 | + /* Keep interrupt polarity active low */ |
---|
| 933 | + regmap_write(map, TVP5150_INT_CONF, TVP5150_VDPOE); |
---|
| 934 | + regmap_write(map, TVP5150_INTT_CONFIG_REG_B, 0x0); |
---|
| 935 | + } |
---|
| 936 | + |
---|
| 937 | + /* Initializes VDP registers */ |
---|
| 938 | + tvp5150_vdp_init(sd); |
---|
| 939 | + |
---|
| 940 | + /* Selects decoder input */ |
---|
| 941 | + tvp5150_selmux(sd); |
---|
| 942 | + |
---|
| 943 | + /* Initialize image preferences */ |
---|
| 944 | + v4l2_ctrl_handler_setup(&decoder->hdl); |
---|
| 945 | + |
---|
| 946 | + return 0; |
---|
| 947 | +} |
---|
| 948 | + |
---|
| 949 | +static int tvp5150_enable(struct v4l2_subdev *sd) |
---|
| 950 | +{ |
---|
| 951 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 952 | + v4l2_std_id std; |
---|
| 953 | + |
---|
| 954 | + /* Initializes TVP5150 to stream enabled values */ |
---|
| 955 | + tvp5150_write_inittab(sd, tvp5150_init_enable); |
---|
| 956 | + |
---|
| 957 | + if (decoder->norm == V4L2_STD_ALL) |
---|
| 958 | + std = tvp5150_read_std(sd); |
---|
| 959 | + else |
---|
| 960 | + std = decoder->norm; |
---|
| 961 | + |
---|
| 962 | + /* Disable autoswitch mode */ |
---|
| 963 | + tvp5150_set_std(sd, std); |
---|
| 964 | + |
---|
| 965 | + /* |
---|
| 966 | + * Enable the YCbCr and clock outputs. In discrete sync mode |
---|
| 967 | + * (non-BT.656) additionally enable the the sync outputs. |
---|
| 968 | + */ |
---|
| 969 | + switch (decoder->mbus_type) { |
---|
| 970 | + case V4L2_MBUS_PARALLEL: |
---|
| 971 | + /* 8-bit 4:2:2 YUV with discrete sync output */ |
---|
| 972 | + regmap_update_bits(decoder->regmap, TVP5150_DATA_RATE_SEL, |
---|
| 973 | + 0x7, 0x0); |
---|
| 974 | + decoder->oe = TVP5150_MISC_CTL_YCBCR_OE | |
---|
| 975 | + TVP5150_MISC_CTL_CLOCK_OE | |
---|
| 976 | + TVP5150_MISC_CTL_SYNC_OE; |
---|
| 977 | + break; |
---|
| 978 | + case V4L2_MBUS_BT656: |
---|
| 979 | + decoder->oe = TVP5150_MISC_CTL_YCBCR_OE | |
---|
| 980 | + TVP5150_MISC_CTL_CLOCK_OE; |
---|
| 981 | + break; |
---|
| 982 | + default: |
---|
| 983 | + return -EINVAL; |
---|
| 984 | + } |
---|
| 985 | + |
---|
| 986 | + return 0; |
---|
| 987 | +}; |
---|
| 988 | + |
---|
| 989 | +static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl) |
---|
| 990 | +{ |
---|
| 991 | + struct v4l2_subdev *sd = to_sd(ctrl); |
---|
| 992 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 993 | + |
---|
| 994 | + switch (ctrl->id) { |
---|
| 995 | + case V4L2_CID_BRIGHTNESS: |
---|
| 996 | + regmap_write(decoder->regmap, TVP5150_BRIGHT_CTL, ctrl->val); |
---|
| 997 | + return 0; |
---|
| 998 | + case V4L2_CID_CONTRAST: |
---|
| 999 | + regmap_write(decoder->regmap, TVP5150_CONTRAST_CTL, ctrl->val); |
---|
| 1000 | + return 0; |
---|
| 1001 | + case V4L2_CID_SATURATION: |
---|
| 1002 | + regmap_write(decoder->regmap, TVP5150_SATURATION_CTL, |
---|
| 1003 | + ctrl->val); |
---|
| 1004 | + return 0; |
---|
| 1005 | + case V4L2_CID_HUE: |
---|
| 1006 | + regmap_write(decoder->regmap, TVP5150_HUE_CTL, ctrl->val); |
---|
| 1007 | + return 0; |
---|
| 1008 | + case V4L2_CID_TEST_PATTERN: |
---|
| 1009 | + decoder->enable = ctrl->val ? false : true; |
---|
| 1010 | + tvp5150_selmux(sd); |
---|
| 1011 | + return 0; |
---|
| 1012 | + } |
---|
| 1013 | + return -EINVAL; |
---|
| 1014 | +} |
---|
| 1015 | + |
---|
| 1016 | +static void tvp5150_set_default(v4l2_std_id std, struct v4l2_rect *crop) |
---|
| 1017 | +{ |
---|
| 1018 | + /* Default is no cropping */ |
---|
| 1019 | + crop->top = 0; |
---|
| 1020 | + crop->left = 0; |
---|
| 1021 | + crop->width = TVP5150_H_MAX; |
---|
| 1022 | + if (std & V4L2_STD_525_60) |
---|
| 1023 | + crop->height = TVP5150_V_MAX_525_60; |
---|
| 1024 | + else |
---|
| 1025 | + crop->height = TVP5150_V_MAX_OTHERS; |
---|
| 1026 | +} |
---|
| 1027 | + |
---|
| 1028 | +static struct v4l2_rect * |
---|
| 1029 | +tvp5150_get_pad_crop(struct tvp5150 *decoder, |
---|
| 1030 | + struct v4l2_subdev_pad_config *cfg, unsigned int pad, |
---|
| 1031 | + enum v4l2_subdev_format_whence which) |
---|
| 1032 | +{ |
---|
| 1033 | + switch (which) { |
---|
| 1034 | + case V4L2_SUBDEV_FORMAT_ACTIVE: |
---|
| 1035 | + return &decoder->rect; |
---|
| 1036 | + case V4L2_SUBDEV_FORMAT_TRY: |
---|
| 1037 | +#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) |
---|
| 1038 | + return v4l2_subdev_get_try_crop(&decoder->sd, cfg, pad); |
---|
| 1039 | +#else |
---|
| 1040 | + return ERR_PTR(-EINVAL); |
---|
| 1041 | +#endif |
---|
| 1042 | + default: |
---|
| 1043 | + return ERR_PTR(-EINVAL); |
---|
| 1044 | + } |
---|
| 1045 | +} |
---|
| 1046 | + |
---|
862 | 1047 | static int tvp5150_fill_fmt(struct v4l2_subdev *sd, |
---|
863 | | - struct v4l2_subdev_pad_config *cfg, |
---|
864 | | - struct v4l2_subdev_format *format) |
---|
| 1048 | + struct v4l2_subdev_pad_config *cfg, |
---|
| 1049 | + struct v4l2_subdev_format *format) |
---|
865 | 1050 | { |
---|
866 | 1051 | struct v4l2_mbus_framefmt *f; |
---|
867 | 1052 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
868 | 1053 | |
---|
869 | | - if (!format || (format->pad != DEMOD_PAD_VID_OUT)) |
---|
| 1054 | + if (!format || (format->pad != TVP5150_PAD_VID_OUT)) |
---|
870 | 1055 | return -EINVAL; |
---|
871 | 1056 | |
---|
872 | 1057 | f = &format->format; |
---|
.. | .. |
---|
874 | 1059 | f->width = decoder->rect.width; |
---|
875 | 1060 | f->height = decoder->rect.height / 2; |
---|
876 | 1061 | |
---|
877 | | - f->code = MEDIA_BUS_FMT_UYVY8_2X8; |
---|
878 | | - f->field = V4L2_FIELD_ALTERNATE; |
---|
879 | | - f->colorspace = V4L2_COLORSPACE_SMPTE170M; |
---|
| 1062 | + f->code = TVP5150_MBUS_FMT; |
---|
| 1063 | + f->field = TVP5150_FIELD; |
---|
| 1064 | + f->colorspace = TVP5150_COLORSPACE; |
---|
880 | 1065 | |
---|
881 | 1066 | dev_dbg_lvl(sd->dev, 1, debug, "width = %d, height = %d\n", f->width, |
---|
882 | | - f->height); |
---|
| 1067 | + f->height); |
---|
883 | 1068 | return 0; |
---|
884 | 1069 | } |
---|
885 | 1070 | |
---|
886 | | -static int tvp5150_set_selection(struct v4l2_subdev *sd, |
---|
887 | | - struct v4l2_subdev_pad_config *cfg, |
---|
888 | | - struct v4l2_subdev_selection *sel) |
---|
| 1071 | +static unsigned int tvp5150_get_hmax(struct v4l2_subdev *sd) |
---|
889 | 1072 | { |
---|
890 | 1073 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
891 | | - struct v4l2_rect rect = sel->r; |
---|
892 | 1074 | v4l2_std_id std; |
---|
893 | | - int hmax; |
---|
894 | | - |
---|
895 | | - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || |
---|
896 | | - sel->target != V4L2_SEL_TGT_CROP) |
---|
897 | | - return -EINVAL; |
---|
898 | | - |
---|
899 | | - dev_dbg_lvl(sd->dev, 1, debug, "%s left=%d, top=%d, width=%d, height=%d\n", |
---|
900 | | - __func__, rect.left, rect.top, rect.width, rect.height); |
---|
901 | | - |
---|
902 | | - /* tvp5150 has some special limits */ |
---|
903 | | - rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT); |
---|
904 | | - rect.top = clamp(rect.top, 0, TVP5150_MAX_CROP_TOP); |
---|
905 | 1075 | |
---|
906 | 1076 | /* Calculate height based on current standard */ |
---|
907 | 1077 | if (decoder->norm == V4L2_STD_ALL) |
---|
.. | .. |
---|
909 | 1079 | else |
---|
910 | 1080 | std = decoder->norm; |
---|
911 | 1081 | |
---|
912 | | - if (std & V4L2_STD_525_60) |
---|
913 | | - hmax = TVP5150_V_MAX_525_60; |
---|
914 | | - else |
---|
915 | | - hmax = TVP5150_V_MAX_OTHERS; |
---|
| 1082 | + return (std & V4L2_STD_525_60) ? |
---|
| 1083 | + TVP5150_V_MAX_525_60 : TVP5150_V_MAX_OTHERS; |
---|
| 1084 | +} |
---|
| 1085 | + |
---|
| 1086 | +static void tvp5150_set_hw_selection(struct v4l2_subdev *sd, |
---|
| 1087 | + struct v4l2_rect *rect) |
---|
| 1088 | +{ |
---|
| 1089 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1090 | + unsigned int hmax = tvp5150_get_hmax(sd); |
---|
| 1091 | + |
---|
| 1092 | + regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, rect->top); |
---|
| 1093 | + regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP, |
---|
| 1094 | + rect->top + rect->height - hmax); |
---|
| 1095 | + regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_MSB, |
---|
| 1096 | + rect->left >> TVP5150_CROP_SHIFT); |
---|
| 1097 | + regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_ST_LSB, |
---|
| 1098 | + rect->left | (1 << TVP5150_CROP_SHIFT)); |
---|
| 1099 | + regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_MSB, |
---|
| 1100 | + (rect->left + rect->width - TVP5150_MAX_CROP_LEFT) >> |
---|
| 1101 | + TVP5150_CROP_SHIFT); |
---|
| 1102 | + regmap_write(decoder->regmap, TVP5150_ACT_VD_CROP_STP_LSB, |
---|
| 1103 | + rect->left + rect->width - TVP5150_MAX_CROP_LEFT); |
---|
| 1104 | +} |
---|
| 1105 | + |
---|
| 1106 | +static int tvp5150_set_selection(struct v4l2_subdev *sd, |
---|
| 1107 | + struct v4l2_subdev_pad_config *cfg, |
---|
| 1108 | + struct v4l2_subdev_selection *sel) |
---|
| 1109 | +{ |
---|
| 1110 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1111 | + struct v4l2_rect *rect = &sel->r; |
---|
| 1112 | + struct v4l2_rect *crop; |
---|
| 1113 | + unsigned int hmax; |
---|
| 1114 | + |
---|
| 1115 | + if (sel->target != V4L2_SEL_TGT_CROP) |
---|
| 1116 | + return -EINVAL; |
---|
| 1117 | + |
---|
| 1118 | + dev_dbg_lvl(sd->dev, 1, debug, "%s left=%d, top=%d, width=%d, height=%d\n", |
---|
| 1119 | + __func__, rect->left, rect->top, rect->width, rect->height); |
---|
| 1120 | + |
---|
| 1121 | + /* tvp5150 has some special limits */ |
---|
| 1122 | + rect->left = clamp(rect->left, 0, TVP5150_MAX_CROP_LEFT); |
---|
| 1123 | + rect->top = clamp(rect->top, 0, TVP5150_MAX_CROP_TOP); |
---|
| 1124 | + hmax = tvp5150_get_hmax(sd); |
---|
916 | 1125 | |
---|
917 | 1126 | /* |
---|
918 | 1127 | * alignments: |
---|
919 | 1128 | * - width = 2 due to UYVY colorspace |
---|
920 | 1129 | * - height, image = no special alignment |
---|
921 | 1130 | */ |
---|
922 | | - v4l_bound_align_image(&rect.width, |
---|
923 | | - TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect.left, |
---|
924 | | - TVP5150_H_MAX - rect.left, 1, &rect.height, |
---|
925 | | - hmax - TVP5150_MAX_CROP_TOP - rect.top, |
---|
926 | | - hmax - rect.top, 0, 0); |
---|
| 1131 | + v4l_bound_align_image(&rect->width, |
---|
| 1132 | + TVP5150_H_MAX - TVP5150_MAX_CROP_LEFT - rect->left, |
---|
| 1133 | + TVP5150_H_MAX - rect->left, 1, &rect->height, |
---|
| 1134 | + hmax - TVP5150_MAX_CROP_TOP - rect->top, |
---|
| 1135 | + hmax - rect->top, 0, 0); |
---|
927 | 1136 | |
---|
928 | | - tvp5150_write(sd, TVP5150_VERT_BLANKING_START, rect.top); |
---|
929 | | - tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, |
---|
930 | | - rect.top + rect.height - hmax); |
---|
931 | | - tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_MSB, |
---|
932 | | - rect.left >> TVP5150_CROP_SHIFT); |
---|
933 | | - tvp5150_write(sd, TVP5150_ACT_VD_CROP_ST_LSB, |
---|
934 | | - rect.left | (1 << TVP5150_CROP_SHIFT)); |
---|
935 | | - tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_MSB, |
---|
936 | | - (rect.left + rect.width - TVP5150_MAX_CROP_LEFT) >> |
---|
937 | | - TVP5150_CROP_SHIFT); |
---|
938 | | - tvp5150_write(sd, TVP5150_ACT_VD_CROP_STP_LSB, |
---|
939 | | - rect.left + rect.width - TVP5150_MAX_CROP_LEFT); |
---|
| 1137 | + if (!IS_ENABLED(CONFIG_VIDEO_V4L2_SUBDEV_API) && |
---|
| 1138 | + sel->which == V4L2_SUBDEV_FORMAT_TRY) |
---|
| 1139 | + return 0; |
---|
940 | 1140 | |
---|
941 | | - decoder->rect = rect; |
---|
| 1141 | + crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad, sel->which); |
---|
| 1142 | + if (IS_ERR(crop)) |
---|
| 1143 | + return PTR_ERR(crop); |
---|
| 1144 | + |
---|
| 1145 | + /* |
---|
| 1146 | + * Update output image size if the selection (crop) rectangle size or |
---|
| 1147 | + * position has been modified. |
---|
| 1148 | + */ |
---|
| 1149 | + if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE && |
---|
| 1150 | + !v4l2_rect_equal(rect, crop)) |
---|
| 1151 | + tvp5150_set_hw_selection(sd, rect); |
---|
| 1152 | + |
---|
| 1153 | + *crop = *rect; |
---|
942 | 1154 | |
---|
943 | 1155 | return 0; |
---|
944 | 1156 | } |
---|
.. | .. |
---|
948 | 1160 | struct v4l2_subdev_selection *sel) |
---|
949 | 1161 | { |
---|
950 | 1162 | struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); |
---|
| 1163 | + struct v4l2_rect *crop; |
---|
951 | 1164 | v4l2_std_id std; |
---|
952 | | - |
---|
953 | | - if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) |
---|
954 | | - return -EINVAL; |
---|
955 | 1165 | |
---|
956 | 1166 | switch (sel->target) { |
---|
957 | 1167 | case V4L2_SEL_TGT_CROP_BOUNDS: |
---|
958 | | - case V4L2_SEL_TGT_CROP_DEFAULT: |
---|
959 | 1168 | sel->r.left = 0; |
---|
960 | 1169 | sel->r.top = 0; |
---|
961 | 1170 | sel->r.width = TVP5150_H_MAX; |
---|
.. | .. |
---|
971 | 1180 | sel->r.height = TVP5150_V_MAX_OTHERS; |
---|
972 | 1181 | return 0; |
---|
973 | 1182 | case V4L2_SEL_TGT_CROP: |
---|
974 | | - sel->r = decoder->rect; |
---|
| 1183 | + crop = tvp5150_get_pad_crop(decoder, cfg, sel->pad, |
---|
| 1184 | + sel->which); |
---|
| 1185 | + if (IS_ERR(crop)) |
---|
| 1186 | + return PTR_ERR(crop); |
---|
| 1187 | + sel->r = *crop; |
---|
975 | 1188 | return 0; |
---|
976 | 1189 | default: |
---|
977 | 1190 | return -EINVAL; |
---|
978 | 1191 | } |
---|
979 | 1192 | } |
---|
980 | 1193 | |
---|
981 | | -static int tvp5150_g_mbus_config(struct v4l2_subdev *sd, |
---|
982 | | - struct v4l2_mbus_config *cfg) |
---|
| 1194 | +static int tvp5150_get_mbus_config(struct v4l2_subdev *sd, |
---|
| 1195 | + unsigned int pad, |
---|
| 1196 | + struct v4l2_mbus_config *cfg) |
---|
983 | 1197 | { |
---|
984 | 1198 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
985 | 1199 | |
---|
.. | .. |
---|
993 | 1207 | /**************************************************************************** |
---|
994 | 1208 | V4L2 subdev pad ops |
---|
995 | 1209 | ****************************************************************************/ |
---|
| 1210 | +static int tvp5150_init_cfg(struct v4l2_subdev *sd, |
---|
| 1211 | + struct v4l2_subdev_pad_config *cfg) |
---|
| 1212 | +{ |
---|
| 1213 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1214 | + v4l2_std_id std; |
---|
| 1215 | + |
---|
| 1216 | + /* |
---|
| 1217 | + * Reset selection to maximum on subdev_open() if autodetection is on |
---|
| 1218 | + * and a standard change is detected. |
---|
| 1219 | + */ |
---|
| 1220 | + if (decoder->norm == V4L2_STD_ALL) { |
---|
| 1221 | + std = tvp5150_read_std(sd); |
---|
| 1222 | + if (std != decoder->detected_norm) { |
---|
| 1223 | + decoder->detected_norm = std; |
---|
| 1224 | + tvp5150_set_default(std, &decoder->rect); |
---|
| 1225 | + } |
---|
| 1226 | + } |
---|
| 1227 | + |
---|
| 1228 | + return 0; |
---|
| 1229 | +} |
---|
| 1230 | + |
---|
996 | 1231 | static int tvp5150_enum_mbus_code(struct v4l2_subdev *sd, |
---|
997 | 1232 | struct v4l2_subdev_pad_config *cfg, |
---|
998 | 1233 | struct v4l2_subdev_mbus_code_enum *code) |
---|
.. | .. |
---|
1000 | 1235 | if (code->pad || code->index) |
---|
1001 | 1236 | return -EINVAL; |
---|
1002 | 1237 | |
---|
1003 | | - code->code = MEDIA_BUS_FMT_UYVY8_2X8; |
---|
| 1238 | + code->code = TVP5150_MBUS_FMT; |
---|
1004 | 1239 | return 0; |
---|
1005 | 1240 | } |
---|
1006 | 1241 | |
---|
.. | .. |
---|
1010 | 1245 | { |
---|
1011 | 1246 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
1012 | 1247 | |
---|
1013 | | - if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_UYVY8_2X8) |
---|
| 1248 | + if (fse->index >= 8 || fse->code != TVP5150_MBUS_FMT) |
---|
1014 | 1249 | return -EINVAL; |
---|
1015 | 1250 | |
---|
1016 | | - fse->code = MEDIA_BUS_FMT_UYVY8_2X8; |
---|
| 1251 | + fse->code = TVP5150_MBUS_FMT; |
---|
1017 | 1252 | fse->min_width = decoder->rect.width; |
---|
1018 | 1253 | fse->max_width = decoder->rect.width; |
---|
1019 | 1254 | fse->min_height = decoder->rect.height / 2; |
---|
.. | .. |
---|
1023 | 1258 | } |
---|
1024 | 1259 | |
---|
1025 | 1260 | /**************************************************************************** |
---|
1026 | | - Media entity ops |
---|
| 1261 | + * Media entity ops |
---|
1027 | 1262 | ****************************************************************************/ |
---|
| 1263 | +#if defined(CONFIG_MEDIA_CONTROLLER) |
---|
| 1264 | +static int tvp5150_set_link(struct media_pad *connector_pad, |
---|
| 1265 | + struct media_pad *tvp5150_pad, u32 flags) |
---|
| 1266 | +{ |
---|
| 1267 | + struct media_link *link; |
---|
1028 | 1268 | |
---|
1029 | | -#ifdef CONFIG_MEDIA_CONTROLLER |
---|
| 1269 | + link = media_entity_find_link(connector_pad, tvp5150_pad); |
---|
| 1270 | + if (!link) |
---|
| 1271 | + return -EINVAL; |
---|
| 1272 | + |
---|
| 1273 | + link->flags = flags; |
---|
| 1274 | + link->reverse->flags = link->flags; |
---|
| 1275 | + |
---|
| 1276 | + return 0; |
---|
| 1277 | +} |
---|
| 1278 | + |
---|
| 1279 | +static int tvp5150_disable_all_input_links(struct tvp5150 *decoder) |
---|
| 1280 | +{ |
---|
| 1281 | + struct media_pad *connector_pad; |
---|
| 1282 | + unsigned int i; |
---|
| 1283 | + int err; |
---|
| 1284 | + |
---|
| 1285 | + for (i = 0; i < TVP5150_NUM_PADS - 1; i++) { |
---|
| 1286 | + connector_pad = media_entity_remote_pad(&decoder->pads[i]); |
---|
| 1287 | + if (!connector_pad) |
---|
| 1288 | + continue; |
---|
| 1289 | + |
---|
| 1290 | + err = tvp5150_set_link(connector_pad, &decoder->pads[i], 0); |
---|
| 1291 | + if (err) |
---|
| 1292 | + return err; |
---|
| 1293 | + } |
---|
| 1294 | + |
---|
| 1295 | + return 0; |
---|
| 1296 | +} |
---|
| 1297 | + |
---|
| 1298 | +static int tvp5150_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, |
---|
| 1299 | + u32 config); |
---|
| 1300 | + |
---|
1030 | 1301 | static int tvp5150_link_setup(struct media_entity *entity, |
---|
1031 | | - const struct media_pad *local, |
---|
| 1302 | + const struct media_pad *tvp5150_pad, |
---|
1032 | 1303 | const struct media_pad *remote, u32 flags) |
---|
1033 | 1304 | { |
---|
1034 | 1305 | struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); |
---|
1035 | 1306 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
1036 | | - int i; |
---|
| 1307 | + struct media_pad *other_tvp5150_pad = |
---|
| 1308 | + &decoder->pads[tvp5150_pad->index ^ 1]; |
---|
| 1309 | + struct v4l2_fwnode_connector *v4l2c; |
---|
| 1310 | + bool is_svideo = false; |
---|
| 1311 | + unsigned int i; |
---|
| 1312 | + int err; |
---|
1037 | 1313 | |
---|
1038 | | - for (i = 0; i < TVP5150_INPUT_NUM; i++) { |
---|
1039 | | - if (remote->entity == &decoder->input_ent[i]) |
---|
1040 | | - break; |
---|
1041 | | - } |
---|
1042 | | - |
---|
1043 | | - /* Do nothing for entities that are not input connectors */ |
---|
1044 | | - if (i == TVP5150_INPUT_NUM) |
---|
| 1314 | + /* |
---|
| 1315 | + * The TVP5150 state is determined by the enabled sink pad link(s). |
---|
| 1316 | + * Enabling or disabling the source pad link has no effect. |
---|
| 1317 | + */ |
---|
| 1318 | + if (tvp5150_pad->flags & MEDIA_PAD_FL_SOURCE) |
---|
1045 | 1319 | return 0; |
---|
1046 | 1320 | |
---|
1047 | | - decoder->input = i; |
---|
| 1321 | + /* Check if the svideo connector should be enabled */ |
---|
| 1322 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 1323 | + if (remote->entity == &decoder->connectors[i].ent) { |
---|
| 1324 | + v4l2c = &decoder->connectors[i].base; |
---|
| 1325 | + is_svideo = v4l2c->type == V4L2_CONN_SVIDEO; |
---|
| 1326 | + break; |
---|
| 1327 | + } |
---|
| 1328 | + } |
---|
1048 | 1329 | |
---|
1049 | | - tvp5150_selmux(sd); |
---|
| 1330 | + dev_dbg_lvl(sd->dev, 1, debug, "link setup '%s':%d->'%s':%d[%d]", |
---|
| 1331 | + remote->entity->name, remote->index, |
---|
| 1332 | + tvp5150_pad->entity->name, tvp5150_pad->index, |
---|
| 1333 | + flags & MEDIA_LNK_FL_ENABLED); |
---|
| 1334 | + if (is_svideo) |
---|
| 1335 | + dev_dbg_lvl(sd->dev, 1, debug, |
---|
| 1336 | + "link setup '%s':%d->'%s':%d[%d]", |
---|
| 1337 | + remote->entity->name, remote->index, |
---|
| 1338 | + other_tvp5150_pad->entity->name, |
---|
| 1339 | + other_tvp5150_pad->index, |
---|
| 1340 | + flags & MEDIA_LNK_FL_ENABLED); |
---|
| 1341 | + |
---|
| 1342 | + /* |
---|
| 1343 | + * The TVP5150 has an internal mux which allows the following setup: |
---|
| 1344 | + * |
---|
| 1345 | + * comp-connector1 --\ |
---|
| 1346 | + * |---> AIP1A |
---|
| 1347 | + * / |
---|
| 1348 | + * svideo-connector -| |
---|
| 1349 | + * \ |
---|
| 1350 | + * |---> AIP1B |
---|
| 1351 | + * comp-connector2 --/ |
---|
| 1352 | + * |
---|
| 1353 | + * We can't rely on user space that the current connector gets disabled |
---|
| 1354 | + * first before enabling the new connector. Disable all active |
---|
| 1355 | + * connector links to be on the safe side. |
---|
| 1356 | + */ |
---|
| 1357 | + err = tvp5150_disable_all_input_links(decoder); |
---|
| 1358 | + if (err) |
---|
| 1359 | + return err; |
---|
| 1360 | + |
---|
| 1361 | + tvp5150_s_routing(sd, is_svideo ? TVP5150_SVIDEO : tvp5150_pad->index, |
---|
| 1362 | + flags & MEDIA_LNK_FL_ENABLED ? TVP5150_NORMAL : |
---|
| 1363 | + TVP5150_BLACK_SCREEN, 0); |
---|
| 1364 | + |
---|
| 1365 | + if (flags & MEDIA_LNK_FL_ENABLED) { |
---|
| 1366 | + struct v4l2_fwnode_connector_analog *v4l2ca; |
---|
| 1367 | + u32 new_norm; |
---|
| 1368 | + |
---|
| 1369 | + /* |
---|
| 1370 | + * S-Video connector is conneted to both ports AIP1A and AIP1B. |
---|
| 1371 | + * Both links must be enabled in one-shot regardless which link |
---|
| 1372 | + * the user requests. |
---|
| 1373 | + */ |
---|
| 1374 | + if (is_svideo) { |
---|
| 1375 | + err = tvp5150_set_link((struct media_pad *)remote, |
---|
| 1376 | + other_tvp5150_pad, flags); |
---|
| 1377 | + if (err) |
---|
| 1378 | + return err; |
---|
| 1379 | + } |
---|
| 1380 | + |
---|
| 1381 | + if (!decoder->connectors_num) |
---|
| 1382 | + return 0; |
---|
| 1383 | + |
---|
| 1384 | + /* Update the current connector */ |
---|
| 1385 | + decoder->cur_connector = |
---|
| 1386 | + container_of(remote, struct tvp5150_connector, pad); |
---|
| 1387 | + |
---|
| 1388 | + /* |
---|
| 1389 | + * Do nothing if the new connector supports the same tv-norms as |
---|
| 1390 | + * the old one. |
---|
| 1391 | + */ |
---|
| 1392 | + v4l2ca = &decoder->cur_connector->base.connector.analog; |
---|
| 1393 | + new_norm = decoder->norm & v4l2ca->sdtv_stds; |
---|
| 1394 | + if (decoder->norm == new_norm) |
---|
| 1395 | + return 0; |
---|
| 1396 | + |
---|
| 1397 | + /* |
---|
| 1398 | + * Fallback to the new connector tv-norms if we can't find any |
---|
| 1399 | + * common between the current tv-norm and the new one. |
---|
| 1400 | + */ |
---|
| 1401 | + tvp5150_s_std(sd, new_norm ? new_norm : v4l2ca->sdtv_stds); |
---|
| 1402 | + } |
---|
1050 | 1403 | |
---|
1051 | 1404 | return 0; |
---|
1052 | 1405 | } |
---|
.. | .. |
---|
1055 | 1408 | .link_setup = tvp5150_link_setup, |
---|
1056 | 1409 | }; |
---|
1057 | 1410 | #endif |
---|
1058 | | - |
---|
1059 | 1411 | /**************************************************************************** |
---|
1060 | 1412 | I2C Command |
---|
1061 | 1413 | ****************************************************************************/ |
---|
| 1414 | +static int __maybe_unused tvp5150_runtime_suspend(struct device *dev) |
---|
| 1415 | +{ |
---|
| 1416 | + struct i2c_client *client = to_i2c_client(dev); |
---|
| 1417 | + struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
| 1418 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1419 | + |
---|
| 1420 | + if (decoder->irq) |
---|
| 1421 | + /* Disable lock interrupt */ |
---|
| 1422 | + return regmap_update_bits(decoder->regmap, |
---|
| 1423 | + TVP5150_INT_ENABLE_REG_A, |
---|
| 1424 | + TVP5150_INT_A_LOCK, 0); |
---|
| 1425 | + return 0; |
---|
| 1426 | +} |
---|
| 1427 | + |
---|
| 1428 | +static int __maybe_unused tvp5150_runtime_resume(struct device *dev) |
---|
| 1429 | +{ |
---|
| 1430 | + struct i2c_client *client = to_i2c_client(dev); |
---|
| 1431 | + struct v4l2_subdev *sd = i2c_get_clientdata(client); |
---|
| 1432 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1433 | + |
---|
| 1434 | + if (decoder->irq) |
---|
| 1435 | + /* Enable lock interrupt */ |
---|
| 1436 | + return regmap_update_bits(decoder->regmap, |
---|
| 1437 | + TVP5150_INT_ENABLE_REG_A, |
---|
| 1438 | + TVP5150_INT_A_LOCK, |
---|
| 1439 | + TVP5150_INT_A_LOCK); |
---|
| 1440 | + return 0; |
---|
| 1441 | +} |
---|
1062 | 1442 | |
---|
1063 | 1443 | static int tvp5150_s_stream(struct v4l2_subdev *sd, int enable) |
---|
1064 | 1444 | { |
---|
1065 | 1445 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
1066 | | - int val; |
---|
| 1446 | + unsigned int mask, val = 0; |
---|
| 1447 | + int ret; |
---|
1067 | 1448 | |
---|
1068 | | - /* Enable or disable the video output signals. */ |
---|
1069 | | - val = tvp5150_read(sd, TVP5150_MISC_CTL); |
---|
1070 | | - if (val < 0) |
---|
1071 | | - return val; |
---|
1072 | | - |
---|
1073 | | - val &= ~(TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE | |
---|
1074 | | - TVP5150_MISC_CTL_CLOCK_OE); |
---|
| 1449 | + mask = TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_SYNC_OE | |
---|
| 1450 | + TVP5150_MISC_CTL_CLOCK_OE; |
---|
1075 | 1451 | |
---|
1076 | 1452 | if (enable) { |
---|
1077 | | - /* |
---|
1078 | | - * Enable the YCbCr and clock outputs. In discrete sync mode |
---|
1079 | | - * (non-BT.656) additionally enable the the sync outputs. |
---|
1080 | | - */ |
---|
1081 | | - val |= TVP5150_MISC_CTL_YCBCR_OE | TVP5150_MISC_CTL_CLOCK_OE; |
---|
1082 | | - if (decoder->mbus_type == V4L2_MBUS_PARALLEL) |
---|
1083 | | - val |= TVP5150_MISC_CTL_SYNC_OE; |
---|
| 1453 | + ret = pm_runtime_get_sync(sd->dev); |
---|
| 1454 | + if (ret < 0) { |
---|
| 1455 | + pm_runtime_put_noidle(sd->dev); |
---|
| 1456 | + return ret; |
---|
| 1457 | + } |
---|
| 1458 | + |
---|
| 1459 | + tvp5150_enable(sd); |
---|
| 1460 | + |
---|
| 1461 | + /* Enable outputs if decoder is locked */ |
---|
| 1462 | + if (decoder->irq) |
---|
| 1463 | + val = decoder->lock ? decoder->oe : 0; |
---|
| 1464 | + else |
---|
| 1465 | + val = decoder->oe; |
---|
| 1466 | + |
---|
| 1467 | + v4l2_subdev_notify_event(&decoder->sd, &tvp5150_ev_fmt); |
---|
| 1468 | + } else { |
---|
| 1469 | + pm_runtime_put(sd->dev); |
---|
1084 | 1470 | } |
---|
1085 | 1471 | |
---|
1086 | | - tvp5150_write(sd, TVP5150_MISC_CTL, val); |
---|
| 1472 | + regmap_update_bits(decoder->regmap, TVP5150_MISC_CTL, mask, val); |
---|
1087 | 1473 | |
---|
1088 | 1474 | return 0; |
---|
1089 | 1475 | } |
---|
.. | .. |
---|
1107 | 1493 | |
---|
1108 | 1494 | static int tvp5150_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt) |
---|
1109 | 1495 | { |
---|
| 1496 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1497 | + |
---|
1110 | 1498 | /* |
---|
1111 | 1499 | * this is for capturing 36 raw vbi lines |
---|
1112 | 1500 | * if there's a way to cut off the beginning 2 vbi lines |
---|
.. | .. |
---|
1116 | 1504 | */ |
---|
1117 | 1505 | |
---|
1118 | 1506 | if (fmt->sample_format == V4L2_PIX_FMT_GREY) |
---|
1119 | | - tvp5150_write(sd, TVP5150_LUMA_PROC_CTL_1, 0x70); |
---|
| 1507 | + regmap_write(decoder->regmap, TVP5150_LUMA_PROC_CTL_1, 0x70); |
---|
1120 | 1508 | if (fmt->count[0] == 18 && fmt->count[1] == 18) { |
---|
1121 | | - tvp5150_write(sd, TVP5150_VERT_BLANKING_START, 0x00); |
---|
1122 | | - tvp5150_write(sd, TVP5150_VERT_BLANKING_STOP, 0x01); |
---|
| 1509 | + regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_START, |
---|
| 1510 | + 0x00); |
---|
| 1511 | + regmap_write(decoder->regmap, TVP5150_VERT_BLANKING_STOP, 0x01); |
---|
1123 | 1512 | } |
---|
1124 | 1513 | return 0; |
---|
1125 | 1514 | } |
---|
1126 | 1515 | |
---|
1127 | 1516 | static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *svbi) |
---|
1128 | 1517 | { |
---|
| 1518 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
1129 | 1519 | int i; |
---|
1130 | 1520 | |
---|
1131 | 1521 | if (svbi->service_set != 0) { |
---|
.. | .. |
---|
1136 | 1526 | 0xf0, i, 3); |
---|
1137 | 1527 | } |
---|
1138 | 1528 | /* Enables FIFO */ |
---|
1139 | | - tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); |
---|
| 1529 | + regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 1); |
---|
1140 | 1530 | } else { |
---|
1141 | 1531 | /* Disables FIFO*/ |
---|
1142 | | - tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 0); |
---|
| 1532 | + regmap_write(decoder->regmap, TVP5150_FIFO_OUT_CTRL, 0); |
---|
1143 | 1533 | |
---|
1144 | 1534 | /* Disable Full Field */ |
---|
1145 | | - tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); |
---|
| 1535 | + regmap_write(decoder->regmap, TVP5150_FULL_FIELD_ENA, 0); |
---|
1146 | 1536 | |
---|
1147 | 1537 | /* Disable Line modes */ |
---|
1148 | 1538 | for (i = TVP5150_LINE_MODE_INI; i <= TVP5150_LINE_MODE_END; i++) |
---|
1149 | | - tvp5150_write(sd, i, 0xff); |
---|
| 1539 | + regmap_write(decoder->regmap, i, 0xff); |
---|
1150 | 1540 | } |
---|
1151 | 1541 | return 0; |
---|
1152 | 1542 | } |
---|
.. | .. |
---|
1184 | 1574 | |
---|
1185 | 1575 | static int tvp5150_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) |
---|
1186 | 1576 | { |
---|
1187 | | - return tvp5150_write(sd, reg->reg & 0xff, reg->val & 0xff); |
---|
| 1577 | + struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 1578 | + |
---|
| 1579 | + return regmap_write(decoder->regmap, reg->reg & 0xff, reg->val & 0xff); |
---|
1188 | 1580 | } |
---|
1189 | 1581 | #endif |
---|
| 1582 | + |
---|
| 1583 | +static int tvp5150_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, |
---|
| 1584 | + struct v4l2_event_subscription *sub) |
---|
| 1585 | +{ |
---|
| 1586 | + switch (sub->type) { |
---|
| 1587 | + case V4L2_EVENT_SOURCE_CHANGE: |
---|
| 1588 | + return v4l2_src_change_event_subdev_subscribe(sd, fh, sub); |
---|
| 1589 | + case V4L2_EVENT_CTRL: |
---|
| 1590 | + return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub); |
---|
| 1591 | + default: |
---|
| 1592 | + return -EINVAL; |
---|
| 1593 | + } |
---|
| 1594 | +} |
---|
1190 | 1595 | |
---|
1191 | 1596 | static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
---|
1192 | 1597 | { |
---|
.. | .. |
---|
1198 | 1603 | |
---|
1199 | 1604 | static int tvp5150_registered(struct v4l2_subdev *sd) |
---|
1200 | 1605 | { |
---|
1201 | | -#ifdef CONFIG_MEDIA_CONTROLLER |
---|
| 1606 | +#if defined(CONFIG_MEDIA_CONTROLLER) |
---|
1202 | 1607 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
1203 | | - int ret = 0; |
---|
1204 | | - int i; |
---|
| 1608 | + unsigned int i; |
---|
| 1609 | + int ret; |
---|
1205 | 1610 | |
---|
1206 | | - for (i = 0; i < TVP5150_INPUT_NUM; i++) { |
---|
1207 | | - struct media_entity *input = &decoder->input_ent[i]; |
---|
1208 | | - struct media_pad *pad = &decoder->input_pad[i]; |
---|
| 1611 | + /* |
---|
| 1612 | + * Setup connector pads and links. Enable the link to the first |
---|
| 1613 | + * available connector per default. |
---|
| 1614 | + */ |
---|
| 1615 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 1616 | + struct media_entity *con = &decoder->connectors[i].ent; |
---|
| 1617 | + struct media_pad *pad = &decoder->connectors[i].pad; |
---|
| 1618 | + struct v4l2_fwnode_connector *v4l2c = |
---|
| 1619 | + &decoder->connectors[i].base; |
---|
| 1620 | + struct v4l2_connector_link *link = |
---|
| 1621 | + v4l2_connector_first_link(v4l2c); |
---|
| 1622 | + unsigned int port = link->fwnode_link.remote_port; |
---|
| 1623 | + unsigned int flags = i ? 0 : MEDIA_LNK_FL_ENABLED; |
---|
| 1624 | + bool is_svideo = v4l2c->type == V4L2_CONN_SVIDEO; |
---|
1209 | 1625 | |
---|
1210 | | - if (!input->name) |
---|
1211 | | - continue; |
---|
1212 | | - |
---|
1213 | | - decoder->input_pad[i].flags = MEDIA_PAD_FL_SOURCE; |
---|
1214 | | - |
---|
1215 | | - ret = media_entity_pads_init(input, 1, pad); |
---|
| 1626 | + pad->flags = MEDIA_PAD_FL_SOURCE; |
---|
| 1627 | + ret = media_entity_pads_init(con, 1, pad); |
---|
1216 | 1628 | if (ret < 0) |
---|
1217 | | - return ret; |
---|
| 1629 | + goto err; |
---|
1218 | 1630 | |
---|
1219 | | - ret = media_device_register_entity(sd->v4l2_dev->mdev, input); |
---|
| 1631 | + ret = media_device_register_entity(sd->v4l2_dev->mdev, con); |
---|
1220 | 1632 | if (ret < 0) |
---|
1221 | | - return ret; |
---|
| 1633 | + goto err; |
---|
1222 | 1634 | |
---|
1223 | | - ret = media_create_pad_link(input, 0, &sd->entity, |
---|
1224 | | - DEMOD_PAD_IF_INPUT, 0); |
---|
1225 | | - if (ret < 0) { |
---|
1226 | | - media_device_unregister_entity(input); |
---|
1227 | | - return ret; |
---|
| 1635 | + ret = media_create_pad_link(con, 0, &sd->entity, port, flags); |
---|
| 1636 | + if (ret < 0) |
---|
| 1637 | + goto err; |
---|
| 1638 | + |
---|
| 1639 | + if (is_svideo) { |
---|
| 1640 | + /* |
---|
| 1641 | + * Check tvp5150_link_setup() comments for more |
---|
| 1642 | + * information. |
---|
| 1643 | + */ |
---|
| 1644 | + link = v4l2_connector_last_link(v4l2c); |
---|
| 1645 | + port = link->fwnode_link.remote_port; |
---|
| 1646 | + ret = media_create_pad_link(con, 0, &sd->entity, port, |
---|
| 1647 | + flags); |
---|
| 1648 | + if (ret < 0) |
---|
| 1649 | + goto err; |
---|
| 1650 | + } |
---|
| 1651 | + |
---|
| 1652 | + /* Enable default input. */ |
---|
| 1653 | + if (flags == MEDIA_LNK_FL_ENABLED) { |
---|
| 1654 | + decoder->input = |
---|
| 1655 | + is_svideo ? TVP5150_SVIDEO : |
---|
| 1656 | + port == 0 ? TVP5150_COMPOSITE0 : |
---|
| 1657 | + TVP5150_COMPOSITE1; |
---|
| 1658 | + |
---|
| 1659 | + tvp5150_selmux(sd); |
---|
| 1660 | + decoder->cur_connector = &decoder->connectors[i]; |
---|
| 1661 | + tvp5150_s_std(sd, v4l2c->connector.analog.sdtv_stds); |
---|
1228 | 1662 | } |
---|
1229 | 1663 | } |
---|
| 1664 | + |
---|
| 1665 | + return 0; |
---|
| 1666 | + |
---|
| 1667 | +err: |
---|
| 1668 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 1669 | + media_device_unregister_entity(&decoder->connectors[i].ent); |
---|
| 1670 | + media_entity_cleanup(&decoder->connectors[i].ent); |
---|
| 1671 | + } |
---|
| 1672 | + return ret; |
---|
1230 | 1673 | #endif |
---|
| 1674 | + |
---|
| 1675 | + return 0; |
---|
| 1676 | +} |
---|
| 1677 | + |
---|
| 1678 | +static int tvp5150_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
---|
| 1679 | +{ |
---|
| 1680 | + int ret; |
---|
| 1681 | + |
---|
| 1682 | + ret = pm_runtime_get_sync(sd->dev); |
---|
| 1683 | + if (ret < 0) { |
---|
| 1684 | + pm_runtime_put_noidle(sd->dev); |
---|
| 1685 | + return ret; |
---|
| 1686 | + } |
---|
| 1687 | + |
---|
| 1688 | + return 0; |
---|
| 1689 | +} |
---|
| 1690 | + |
---|
| 1691 | +static int tvp5150_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
---|
| 1692 | +{ |
---|
| 1693 | + pm_runtime_put(sd->dev); |
---|
1231 | 1694 | |
---|
1232 | 1695 | return 0; |
---|
1233 | 1696 | } |
---|
.. | .. |
---|
1245 | 1708 | .g_register = tvp5150_g_register, |
---|
1246 | 1709 | .s_register = tvp5150_s_register, |
---|
1247 | 1710 | #endif |
---|
| 1711 | + .subscribe_event = tvp5150_subscribe_event, |
---|
| 1712 | + .unsubscribe_event = v4l2_event_subdev_unsubscribe, |
---|
1248 | 1713 | }; |
---|
1249 | 1714 | |
---|
1250 | 1715 | static const struct v4l2_subdev_tuner_ops tvp5150_tuner_ops = { |
---|
.. | .. |
---|
1253 | 1718 | |
---|
1254 | 1719 | static const struct v4l2_subdev_video_ops tvp5150_video_ops = { |
---|
1255 | 1720 | .s_std = tvp5150_s_std, |
---|
| 1721 | + .g_std = tvp5150_g_std, |
---|
| 1722 | + .querystd = tvp5150_querystd, |
---|
1256 | 1723 | .s_stream = tvp5150_s_stream, |
---|
1257 | 1724 | .s_routing = tvp5150_s_routing, |
---|
1258 | | - .g_mbus_config = tvp5150_g_mbus_config, |
---|
1259 | 1725 | }; |
---|
1260 | 1726 | |
---|
1261 | 1727 | static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = { |
---|
.. | .. |
---|
1266 | 1732 | }; |
---|
1267 | 1733 | |
---|
1268 | 1734 | static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = { |
---|
| 1735 | + .init_cfg = tvp5150_init_cfg, |
---|
1269 | 1736 | .enum_mbus_code = tvp5150_enum_mbus_code, |
---|
1270 | 1737 | .enum_frame_size = tvp5150_enum_frame_size, |
---|
1271 | 1738 | .set_fmt = tvp5150_fill_fmt, |
---|
1272 | 1739 | .get_fmt = tvp5150_fill_fmt, |
---|
1273 | 1740 | .get_selection = tvp5150_get_selection, |
---|
1274 | 1741 | .set_selection = tvp5150_set_selection, |
---|
| 1742 | + .get_mbus_config = tvp5150_get_mbus_config, |
---|
1275 | 1743 | }; |
---|
1276 | 1744 | |
---|
1277 | 1745 | static const struct v4l2_subdev_ops tvp5150_ops = { |
---|
.. | .. |
---|
1284 | 1752 | |
---|
1285 | 1753 | static const struct v4l2_subdev_internal_ops tvp5150_internal_ops = { |
---|
1286 | 1754 | .registered = tvp5150_registered, |
---|
| 1755 | + .open = tvp5150_open, |
---|
| 1756 | + .close = tvp5150_close, |
---|
1287 | 1757 | }; |
---|
1288 | | - |
---|
1289 | 1758 | |
---|
1290 | 1759 | /**************************************************************************** |
---|
1291 | 1760 | I2C Client & Driver |
---|
1292 | 1761 | ****************************************************************************/ |
---|
1293 | 1762 | |
---|
| 1763 | +static const struct regmap_range tvp5150_readable_ranges[] = { |
---|
| 1764 | + { |
---|
| 1765 | + .range_min = TVP5150_VD_IN_SRC_SEL_1, |
---|
| 1766 | + .range_max = TVP5150_AUTOSW_MSK, |
---|
| 1767 | + }, { |
---|
| 1768 | + .range_min = TVP5150_COLOR_KIL_THSH_CTL, |
---|
| 1769 | + .range_max = TVP5150_CONF_SHARED_PIN, |
---|
| 1770 | + }, { |
---|
| 1771 | + .range_min = TVP5150_ACT_VD_CROP_ST_MSB, |
---|
| 1772 | + .range_max = TVP5150_HORIZ_SYNC_START, |
---|
| 1773 | + }, { |
---|
| 1774 | + .range_min = TVP5150_VERT_BLANKING_START, |
---|
| 1775 | + .range_max = TVP5150_INTT_CONFIG_REG_B, |
---|
| 1776 | + }, { |
---|
| 1777 | + .range_min = TVP5150_VIDEO_STD, |
---|
| 1778 | + .range_max = TVP5150_VIDEO_STD, |
---|
| 1779 | + }, { |
---|
| 1780 | + .range_min = TVP5150_CB_GAIN_FACT, |
---|
| 1781 | + .range_max = TVP5150_REV_SELECT, |
---|
| 1782 | + }, { |
---|
| 1783 | + .range_min = TVP5150_MSB_DEV_ID, |
---|
| 1784 | + .range_max = TVP5150_STATUS_REG_5, |
---|
| 1785 | + }, { |
---|
| 1786 | + .range_min = TVP5150_CC_DATA_INI, |
---|
| 1787 | + .range_max = TVP5150_TELETEXT_FIL_ENA, |
---|
| 1788 | + }, { |
---|
| 1789 | + .range_min = TVP5150_INT_STATUS_REG_A, |
---|
| 1790 | + .range_max = TVP5150_FIFO_OUT_CTRL, |
---|
| 1791 | + }, { |
---|
| 1792 | + .range_min = TVP5150_FULL_FIELD_ENA, |
---|
| 1793 | + .range_max = TVP5150_FULL_FIELD_MODE_REG, |
---|
| 1794 | + }, |
---|
| 1795 | +}; |
---|
| 1796 | + |
---|
| 1797 | +static bool tvp5150_volatile_reg(struct device *dev, unsigned int reg) |
---|
| 1798 | +{ |
---|
| 1799 | + switch (reg) { |
---|
| 1800 | + case TVP5150_VERT_LN_COUNT_MSB: |
---|
| 1801 | + case TVP5150_VERT_LN_COUNT_LSB: |
---|
| 1802 | + case TVP5150_INT_STATUS_REG_A: |
---|
| 1803 | + case TVP5150_INT_STATUS_REG_B: |
---|
| 1804 | + case TVP5150_INT_ACTIVE_REG_B: |
---|
| 1805 | + case TVP5150_STATUS_REG_1: |
---|
| 1806 | + case TVP5150_STATUS_REG_2: |
---|
| 1807 | + case TVP5150_STATUS_REG_3: |
---|
| 1808 | + case TVP5150_STATUS_REG_4: |
---|
| 1809 | + case TVP5150_STATUS_REG_5: |
---|
| 1810 | + /* CC, WSS, VPS, VITC data? */ |
---|
| 1811 | + case TVP5150_VBI_FIFO_READ_DATA: |
---|
| 1812 | + case TVP5150_VDP_STATUS_REG: |
---|
| 1813 | + case TVP5150_FIFO_WORD_COUNT: |
---|
| 1814 | + return true; |
---|
| 1815 | + default: |
---|
| 1816 | + return false; |
---|
| 1817 | + } |
---|
| 1818 | +} |
---|
| 1819 | + |
---|
| 1820 | +static const struct regmap_access_table tvp5150_readable_table = { |
---|
| 1821 | + .yes_ranges = tvp5150_readable_ranges, |
---|
| 1822 | + .n_yes_ranges = ARRAY_SIZE(tvp5150_readable_ranges), |
---|
| 1823 | +}; |
---|
| 1824 | + |
---|
| 1825 | +static struct regmap_config tvp5150_config = { |
---|
| 1826 | + .reg_bits = 8, |
---|
| 1827 | + .val_bits = 8, |
---|
| 1828 | + .max_register = 0xff, |
---|
| 1829 | + |
---|
| 1830 | + .cache_type = REGCACHE_RBTREE, |
---|
| 1831 | + |
---|
| 1832 | + .rd_table = &tvp5150_readable_table, |
---|
| 1833 | + .volatile_reg = tvp5150_volatile_reg, |
---|
| 1834 | +}; |
---|
| 1835 | + |
---|
1294 | 1836 | static int tvp5150_detect_version(struct tvp5150 *core) |
---|
1295 | 1837 | { |
---|
1296 | 1838 | struct v4l2_subdev *sd = &core->sd; |
---|
1297 | 1839 | struct i2c_client *c = v4l2_get_subdevdata(sd); |
---|
1298 | | - unsigned int i; |
---|
1299 | 1840 | u8 regs[4]; |
---|
1300 | 1841 | int res; |
---|
1301 | 1842 | |
---|
.. | .. |
---|
1303 | 1844 | * Read consequent registers - TVP5150_MSB_DEV_ID, TVP5150_LSB_DEV_ID, |
---|
1304 | 1845 | * TVP5150_ROM_MAJOR_VER, TVP5150_ROM_MINOR_VER |
---|
1305 | 1846 | */ |
---|
1306 | | - for (i = 0; i < 4; i++) { |
---|
1307 | | - res = tvp5150_read(sd, TVP5150_MSB_DEV_ID + i); |
---|
1308 | | - if (res < 0) |
---|
1309 | | - return res; |
---|
1310 | | - regs[i] = res; |
---|
| 1847 | + res = regmap_bulk_read(core->regmap, TVP5150_MSB_DEV_ID, regs, 4); |
---|
| 1848 | + if (res < 0) { |
---|
| 1849 | + dev_err(&c->dev, "reading ID registers failed: %d\n", res); |
---|
| 1850 | + return res; |
---|
1311 | 1851 | } |
---|
1312 | 1852 | |
---|
1313 | 1853 | core->dev_id = (regs[0] << 8) | regs[1]; |
---|
.. | .. |
---|
1323 | 1863 | dev_info(sd->dev, "tvp5150am1 detected.\n"); |
---|
1324 | 1864 | |
---|
1325 | 1865 | /* ITU-T BT.656.4 timing */ |
---|
1326 | | - tvp5150_write(sd, TVP5150_REV_SELECT, 0); |
---|
| 1866 | + regmap_write(core->regmap, TVP5150_REV_SELECT, 0); |
---|
1327 | 1867 | } else if (core->dev_id == 0x5151 && core->rom_ver == 0x0100) { |
---|
1328 | 1868 | dev_info(sd->dev, "tvp5151 detected.\n"); |
---|
1329 | 1869 | } else { |
---|
.. | .. |
---|
1364 | 1904 | return 0; |
---|
1365 | 1905 | } |
---|
1366 | 1906 | |
---|
| 1907 | +#if defined(CONFIG_MEDIA_CONTROLLER) |
---|
| 1908 | +static int tvp5150_mc_init(struct tvp5150 *decoder) |
---|
| 1909 | +{ |
---|
| 1910 | + struct v4l2_subdev *sd = &decoder->sd; |
---|
| 1911 | + unsigned int i; |
---|
| 1912 | + |
---|
| 1913 | + sd->entity.ops = &tvp5150_sd_media_ops; |
---|
| 1914 | + sd->entity.function = MEDIA_ENT_F_ATV_DECODER; |
---|
| 1915 | + |
---|
| 1916 | + for (i = 0; i < TVP5150_NUM_PADS - 1; i++) { |
---|
| 1917 | + decoder->pads[i].flags = MEDIA_PAD_FL_SINK; |
---|
| 1918 | + decoder->pads[i].sig_type = PAD_SIGNAL_ANALOG; |
---|
| 1919 | + } |
---|
| 1920 | + |
---|
| 1921 | + decoder->pads[i].flags = MEDIA_PAD_FL_SOURCE; |
---|
| 1922 | + decoder->pads[i].sig_type = PAD_SIGNAL_DV; |
---|
| 1923 | + |
---|
| 1924 | + return media_entity_pads_init(&sd->entity, TVP5150_NUM_PADS, |
---|
| 1925 | + decoder->pads); |
---|
| 1926 | +} |
---|
| 1927 | + |
---|
| 1928 | +#else /* !defined(CONFIG_MEDIA_CONTROLLER) */ |
---|
| 1929 | + |
---|
| 1930 | +static inline int tvp5150_mc_init(struct tvp5150 *decoder) |
---|
| 1931 | +{ |
---|
| 1932 | + return 0; |
---|
| 1933 | +} |
---|
| 1934 | +#endif /* defined(CONFIG_MEDIA_CONTROLLER) */ |
---|
| 1935 | + |
---|
| 1936 | +static int tvp5150_validate_connectors(struct tvp5150 *decoder) |
---|
| 1937 | +{ |
---|
| 1938 | + struct device *dev = decoder->sd.dev; |
---|
| 1939 | + struct tvp5150_connector *tvpc; |
---|
| 1940 | + struct v4l2_fwnode_connector *v4l2c; |
---|
| 1941 | + unsigned int i; |
---|
| 1942 | + |
---|
| 1943 | + if (!decoder->connectors_num) { |
---|
| 1944 | + dev_err(dev, "No valid connector found\n"); |
---|
| 1945 | + return -ENODEV; |
---|
| 1946 | + } |
---|
| 1947 | + |
---|
| 1948 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 1949 | + struct v4l2_connector_link *link0 = NULL; |
---|
| 1950 | + struct v4l2_connector_link *link1; |
---|
| 1951 | + |
---|
| 1952 | + tvpc = &decoder->connectors[i]; |
---|
| 1953 | + v4l2c = &tvpc->base; |
---|
| 1954 | + |
---|
| 1955 | + if (v4l2c->type == V4L2_CONN_COMPOSITE) { |
---|
| 1956 | + if (v4l2c->nr_of_links != 1) { |
---|
| 1957 | + dev_err(dev, "Composite: connector needs 1 link\n"); |
---|
| 1958 | + return -EINVAL; |
---|
| 1959 | + } |
---|
| 1960 | + link0 = v4l2_connector_first_link(v4l2c); |
---|
| 1961 | + if (!link0) { |
---|
| 1962 | + dev_err(dev, "Composite: invalid first link\n"); |
---|
| 1963 | + return -EINVAL; |
---|
| 1964 | + } |
---|
| 1965 | + if (link0->fwnode_link.remote_id == 1) { |
---|
| 1966 | + dev_err(dev, "Composite: invalid endpoint id\n"); |
---|
| 1967 | + return -EINVAL; |
---|
| 1968 | + } |
---|
| 1969 | + } |
---|
| 1970 | + |
---|
| 1971 | + if (v4l2c->type == V4L2_CONN_SVIDEO) { |
---|
| 1972 | + if (v4l2c->nr_of_links != 2) { |
---|
| 1973 | + dev_err(dev, "SVideo: connector needs 2 links\n"); |
---|
| 1974 | + return -EINVAL; |
---|
| 1975 | + } |
---|
| 1976 | + link0 = v4l2_connector_first_link(v4l2c); |
---|
| 1977 | + if (!link0) { |
---|
| 1978 | + dev_err(dev, "SVideo: invalid first link\n"); |
---|
| 1979 | + return -EINVAL; |
---|
| 1980 | + } |
---|
| 1981 | + link1 = v4l2_connector_last_link(v4l2c); |
---|
| 1982 | + if (link0->fwnode_link.remote_port == |
---|
| 1983 | + link1->fwnode_link.remote_port) { |
---|
| 1984 | + dev_err(dev, "SVideo: invalid link setup\n"); |
---|
| 1985 | + return -EINVAL; |
---|
| 1986 | + } |
---|
| 1987 | + } |
---|
| 1988 | + |
---|
| 1989 | + if (!(v4l2c->connector.analog.sdtv_stds & TVP5150_STD_MASK)) { |
---|
| 1990 | + dev_err(dev, "Unsupported tv-norm on connector %s\n", |
---|
| 1991 | + v4l2c->name); |
---|
| 1992 | + return -EINVAL; |
---|
| 1993 | + } |
---|
| 1994 | + } |
---|
| 1995 | + |
---|
| 1996 | + return 0; |
---|
| 1997 | +} |
---|
| 1998 | + |
---|
1367 | 1999 | static int tvp5150_parse_dt(struct tvp5150 *decoder, struct device_node *np) |
---|
1368 | 2000 | { |
---|
1369 | | - struct v4l2_fwnode_endpoint bus_cfg; |
---|
1370 | | - struct device_node *ep; |
---|
1371 | | -#ifdef CONFIG_MEDIA_CONTROLLER |
---|
1372 | | - struct device_node *connectors, *child; |
---|
1373 | | - struct media_entity *input; |
---|
1374 | | - const char *name; |
---|
1375 | | - u32 input_type; |
---|
1376 | | -#endif |
---|
1377 | | - unsigned int flags; |
---|
1378 | | - int ret = 0; |
---|
| 2001 | + struct device *dev = decoder->sd.dev; |
---|
| 2002 | + struct v4l2_fwnode_endpoint bus_cfg = { |
---|
| 2003 | + .bus_type = V4L2_MBUS_UNKNOWN |
---|
| 2004 | + }; |
---|
| 2005 | + struct device_node *ep_np; |
---|
| 2006 | + struct tvp5150_connector *tvpc; |
---|
| 2007 | + struct v4l2_fwnode_connector *v4l2c; |
---|
| 2008 | + unsigned int flags, ep_num; |
---|
| 2009 | + unsigned int i; |
---|
| 2010 | + int ret; |
---|
1379 | 2011 | |
---|
1380 | | - ep = of_graph_get_next_endpoint(np, NULL); |
---|
1381 | | - if (!ep) |
---|
| 2012 | + /* At least 1 output and 1 input */ |
---|
| 2013 | + ep_num = of_graph_get_endpoint_count(np); |
---|
| 2014 | + if (ep_num < 2 || ep_num > 5) { |
---|
| 2015 | + dev_err(dev, "At least 1 input and 1 output must be connected to the device.\n"); |
---|
1382 | 2016 | return -EINVAL; |
---|
| 2017 | + } |
---|
1383 | 2018 | |
---|
1384 | | - ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg); |
---|
| 2019 | + /* Layout if all connectors are used: |
---|
| 2020 | + * |
---|
| 2021 | + * tvp-5150 port@0 (AIP1A) |
---|
| 2022 | + * endpoint@0 -----------> Comp0-Con port |
---|
| 2023 | + * endpoint@1 --------+--> Svideo-Con port |
---|
| 2024 | + * tvp-5150 port@1 (AIP1B) | |
---|
| 2025 | + * endpoint@1 --------+ |
---|
| 2026 | + * endpoint@0 -----------> Comp1-Con port |
---|
| 2027 | + * tvp-5150 port@2 |
---|
| 2028 | + * endpoint (video bitstream output at YOUT[0-7] parallel bus) |
---|
| 2029 | + */ |
---|
| 2030 | + for_each_endpoint_of_node(np, ep_np) { |
---|
| 2031 | + struct fwnode_handle *ep_fwnode = of_fwnode_handle(ep_np); |
---|
| 2032 | + unsigned int next_connector = decoder->connectors_num; |
---|
| 2033 | + struct of_endpoint ep; |
---|
| 2034 | + |
---|
| 2035 | + of_graph_parse_endpoint(ep_np, &ep); |
---|
| 2036 | + if (ep.port > 1 || ep.id > 1) { |
---|
| 2037 | + dev_dbg(dev, "Ignore connector on port@%u/ep@%u\n", |
---|
| 2038 | + ep.port, ep.id); |
---|
| 2039 | + continue; |
---|
| 2040 | + } |
---|
| 2041 | + |
---|
| 2042 | + tvpc = &decoder->connectors[next_connector]; |
---|
| 2043 | + v4l2c = &tvpc->base; |
---|
| 2044 | + |
---|
| 2045 | + if (ep.port == 0 || (ep.port == 1 && ep.id == 0)) { |
---|
| 2046 | + ret = v4l2_fwnode_connector_parse(ep_fwnode, v4l2c); |
---|
| 2047 | + if (ret) |
---|
| 2048 | + goto err_put; |
---|
| 2049 | + ret = v4l2_fwnode_connector_add_link(ep_fwnode, v4l2c); |
---|
| 2050 | + if (ret) |
---|
| 2051 | + goto err_put; |
---|
| 2052 | + decoder->connectors_num++; |
---|
| 2053 | + } else { |
---|
| 2054 | + /* Adding the 2nd svideo link */ |
---|
| 2055 | + for (i = 0; i < TVP5150_MAX_CONNECTORS; i++) { |
---|
| 2056 | + tvpc = &decoder->connectors[i]; |
---|
| 2057 | + v4l2c = &tvpc->base; |
---|
| 2058 | + if (v4l2c->type == V4L2_CONN_SVIDEO) |
---|
| 2059 | + break; |
---|
| 2060 | + } |
---|
| 2061 | + |
---|
| 2062 | + ret = v4l2_fwnode_connector_add_link(ep_fwnode, v4l2c); |
---|
| 2063 | + if (ret) |
---|
| 2064 | + goto err_put; |
---|
| 2065 | + } |
---|
| 2066 | + } |
---|
| 2067 | + |
---|
| 2068 | + ret = tvp5150_validate_connectors(decoder); |
---|
1385 | 2069 | if (ret) |
---|
1386 | | - goto err; |
---|
| 2070 | + goto err_free; |
---|
| 2071 | + |
---|
| 2072 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 2073 | + tvpc = &decoder->connectors[i]; |
---|
| 2074 | + v4l2c = &tvpc->base; |
---|
| 2075 | + tvpc->ent.flags = MEDIA_ENT_FL_CONNECTOR; |
---|
| 2076 | + tvpc->ent.function = v4l2c->type == V4L2_CONN_SVIDEO ? |
---|
| 2077 | + MEDIA_ENT_F_CONN_SVIDEO : MEDIA_ENT_F_CONN_COMPOSITE; |
---|
| 2078 | + tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", |
---|
| 2079 | + v4l2c->name, v4l2c->label ? |
---|
| 2080 | + v4l2c->label : ""); |
---|
| 2081 | + if (!tvpc->ent.name) { |
---|
| 2082 | + ret = -ENOMEM; |
---|
| 2083 | + goto err_free; |
---|
| 2084 | + } |
---|
| 2085 | + } |
---|
| 2086 | + |
---|
| 2087 | + ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0); |
---|
| 2088 | + if (!ep_np) { |
---|
| 2089 | + ret = -EINVAL; |
---|
| 2090 | + dev_err(dev, "Error no output endpoint available\n"); |
---|
| 2091 | + goto err_free; |
---|
| 2092 | + } |
---|
| 2093 | + ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_np), &bus_cfg); |
---|
| 2094 | + of_node_put(ep_np); |
---|
| 2095 | + if (ret) |
---|
| 2096 | + goto err_free; |
---|
1387 | 2097 | |
---|
1388 | 2098 | flags = bus_cfg.bus.parallel.flags; |
---|
1389 | | - |
---|
1390 | 2099 | if (bus_cfg.bus_type == V4L2_MBUS_PARALLEL && |
---|
1391 | 2100 | !(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH && |
---|
1392 | 2101 | flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH && |
---|
1393 | 2102 | flags & V4L2_MBUS_FIELD_EVEN_LOW)) { |
---|
1394 | 2103 | ret = -EINVAL; |
---|
1395 | | - goto err; |
---|
| 2104 | + goto err_free; |
---|
1396 | 2105 | } |
---|
1397 | 2106 | |
---|
1398 | 2107 | decoder->mbus_type = bus_cfg.bus_type; |
---|
1399 | 2108 | |
---|
1400 | | -#ifdef CONFIG_MEDIA_CONTROLLER |
---|
1401 | | - connectors = of_get_child_by_name(np, "connectors"); |
---|
| 2109 | + return 0; |
---|
1402 | 2110 | |
---|
1403 | | - if (!connectors) |
---|
1404 | | - goto err; |
---|
| 2111 | +err_put: |
---|
| 2112 | + of_node_put(ep_np); |
---|
| 2113 | +err_free: |
---|
| 2114 | + for (i = 0; i < TVP5150_MAX_CONNECTORS; i++) |
---|
| 2115 | + v4l2_fwnode_connector_free(&decoder->connectors[i].base); |
---|
1405 | 2116 | |
---|
1406 | | - for_each_available_child_of_node(connectors, child) { |
---|
1407 | | - ret = of_property_read_u32(child, "input", &input_type); |
---|
1408 | | - if (ret) { |
---|
1409 | | - dev_err(decoder->sd.dev, |
---|
1410 | | - "missing type property in node %s\n", |
---|
1411 | | - child->name); |
---|
1412 | | - goto err_connector; |
---|
1413 | | - } |
---|
1414 | | - |
---|
1415 | | - if (input_type >= TVP5150_INPUT_NUM) { |
---|
1416 | | - ret = -EINVAL; |
---|
1417 | | - goto err_connector; |
---|
1418 | | - } |
---|
1419 | | - |
---|
1420 | | - input = &decoder->input_ent[input_type]; |
---|
1421 | | - |
---|
1422 | | - /* Each input connector can only be defined once */ |
---|
1423 | | - if (input->name) { |
---|
1424 | | - dev_err(decoder->sd.dev, |
---|
1425 | | - "input %s with same type already exists\n", |
---|
1426 | | - input->name); |
---|
1427 | | - ret = -EINVAL; |
---|
1428 | | - goto err_connector; |
---|
1429 | | - } |
---|
1430 | | - |
---|
1431 | | - switch (input_type) { |
---|
1432 | | - case TVP5150_COMPOSITE0: |
---|
1433 | | - case TVP5150_COMPOSITE1: |
---|
1434 | | - input->function = MEDIA_ENT_F_CONN_COMPOSITE; |
---|
1435 | | - break; |
---|
1436 | | - case TVP5150_SVIDEO: |
---|
1437 | | - input->function = MEDIA_ENT_F_CONN_SVIDEO; |
---|
1438 | | - break; |
---|
1439 | | - } |
---|
1440 | | - |
---|
1441 | | - input->flags = MEDIA_ENT_FL_CONNECTOR; |
---|
1442 | | - |
---|
1443 | | - ret = of_property_read_string(child, "label", &name); |
---|
1444 | | - if (ret < 0) { |
---|
1445 | | - dev_err(decoder->sd.dev, |
---|
1446 | | - "missing label property in node %s\n", |
---|
1447 | | - child->name); |
---|
1448 | | - goto err_connector; |
---|
1449 | | - } |
---|
1450 | | - |
---|
1451 | | - input->name = name; |
---|
1452 | | - } |
---|
1453 | | - |
---|
1454 | | -err_connector: |
---|
1455 | | - of_node_put(connectors); |
---|
1456 | | -#endif |
---|
1457 | | -err: |
---|
1458 | | - of_node_put(ep); |
---|
1459 | 2117 | return ret; |
---|
1460 | 2118 | } |
---|
1461 | 2119 | |
---|
.. | .. |
---|
1464 | 2122 | "Black screen" |
---|
1465 | 2123 | }; |
---|
1466 | 2124 | |
---|
1467 | | -static int tvp5150_probe(struct i2c_client *c, |
---|
1468 | | - const struct i2c_device_id *id) |
---|
| 2125 | +static int tvp5150_probe(struct i2c_client *c) |
---|
1469 | 2126 | { |
---|
1470 | 2127 | struct tvp5150 *core; |
---|
1471 | 2128 | struct v4l2_subdev *sd; |
---|
1472 | 2129 | struct device_node *np = c->dev.of_node; |
---|
| 2130 | + struct regmap *map; |
---|
| 2131 | + unsigned int i; |
---|
1473 | 2132 | int res; |
---|
1474 | 2133 | |
---|
1475 | 2134 | /* Check if the adapter supports the needed features */ |
---|
.. | .. |
---|
1485 | 2144 | if (!core) |
---|
1486 | 2145 | return -ENOMEM; |
---|
1487 | 2146 | |
---|
| 2147 | + map = devm_regmap_init_i2c(c, &tvp5150_config); |
---|
| 2148 | + if (IS_ERR(map)) |
---|
| 2149 | + return PTR_ERR(map); |
---|
| 2150 | + |
---|
| 2151 | + core->regmap = map; |
---|
1488 | 2152 | sd = &core->sd; |
---|
| 2153 | + v4l2_i2c_subdev_init(sd, c, &tvp5150_ops); |
---|
| 2154 | + sd->internal_ops = &tvp5150_internal_ops; |
---|
| 2155 | + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; |
---|
1489 | 2156 | |
---|
1490 | 2157 | if (IS_ENABLED(CONFIG_OF) && np) { |
---|
1491 | 2158 | res = tvp5150_parse_dt(core, np); |
---|
.. | .. |
---|
1498 | 2165 | core->mbus_type = V4L2_MBUS_BT656; |
---|
1499 | 2166 | } |
---|
1500 | 2167 | |
---|
1501 | | - v4l2_i2c_subdev_init(sd, c, &tvp5150_ops); |
---|
1502 | | - sd->internal_ops = &tvp5150_internal_ops; |
---|
1503 | | - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
---|
1504 | | - |
---|
1505 | | -#if defined(CONFIG_MEDIA_CONTROLLER) |
---|
1506 | | - core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK; |
---|
1507 | | - core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; |
---|
1508 | | - core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE; |
---|
1509 | | - |
---|
1510 | | - sd->entity.function = MEDIA_ENT_F_ATV_DECODER; |
---|
1511 | | - |
---|
1512 | | - res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads); |
---|
1513 | | - if (res < 0) |
---|
| 2168 | + res = tvp5150_mc_init(core); |
---|
| 2169 | + if (res) |
---|
1514 | 2170 | return res; |
---|
1515 | | - |
---|
1516 | | - sd->entity.ops = &tvp5150_sd_media_ops; |
---|
1517 | | -#endif |
---|
1518 | 2171 | |
---|
1519 | 2172 | res = tvp5150_detect_version(core); |
---|
1520 | 2173 | if (res < 0) |
---|
1521 | 2174 | return res; |
---|
1522 | 2175 | |
---|
1523 | | - core->norm = V4L2_STD_ALL; /* Default is autodetect */ |
---|
| 2176 | + /* |
---|
| 2177 | + * Iterate over all available connectors in case they are supported and |
---|
| 2178 | + * successfully parsed. Fallback to default autodetect in case they |
---|
| 2179 | + * aren't supported. |
---|
| 2180 | + */ |
---|
| 2181 | + for (i = 0; i < core->connectors_num; i++) { |
---|
| 2182 | + struct v4l2_fwnode_connector *v4l2c; |
---|
| 2183 | + |
---|
| 2184 | + v4l2c = &core->connectors[i].base; |
---|
| 2185 | + core->norm |= v4l2c->connector.analog.sdtv_stds; |
---|
| 2186 | + } |
---|
| 2187 | + |
---|
| 2188 | + if (!core->connectors_num) |
---|
| 2189 | + core->norm = V4L2_STD_ALL; |
---|
| 2190 | + |
---|
| 2191 | + core->detected_norm = V4L2_STD_UNKNOWN; |
---|
1524 | 2192 | core->input = TVP5150_COMPOSITE1; |
---|
1525 | 2193 | core->enable = true; |
---|
1526 | 2194 | |
---|
.. | .. |
---|
1546 | 2214 | goto err; |
---|
1547 | 2215 | } |
---|
1548 | 2216 | |
---|
1549 | | - /* Default is no cropping */ |
---|
1550 | | - core->rect.top = 0; |
---|
1551 | | - if (tvp5150_read_std(sd) & V4L2_STD_525_60) |
---|
1552 | | - core->rect.height = TVP5150_V_MAX_525_60; |
---|
1553 | | - else |
---|
1554 | | - core->rect.height = TVP5150_V_MAX_OTHERS; |
---|
1555 | | - core->rect.left = 0; |
---|
1556 | | - core->rect.width = TVP5150_H_MAX; |
---|
| 2217 | + tvp5150_set_default(tvp5150_read_std(sd), &core->rect); |
---|
1557 | 2218 | |
---|
| 2219 | + core->irq = c->irq; |
---|
1558 | 2220 | tvp5150_reset(sd, 0); /* Calls v4l2_ctrl_handler_setup() */ |
---|
| 2221 | + if (c->irq) { |
---|
| 2222 | + res = devm_request_threaded_irq(&c->dev, c->irq, NULL, |
---|
| 2223 | + tvp5150_isr, IRQF_TRIGGER_HIGH | |
---|
| 2224 | + IRQF_ONESHOT, "tvp5150", core); |
---|
| 2225 | + if (res) |
---|
| 2226 | + goto err; |
---|
| 2227 | + } |
---|
1559 | 2228 | |
---|
1560 | 2229 | res = v4l2_async_register_subdev(sd); |
---|
1561 | 2230 | if (res < 0) |
---|
.. | .. |
---|
1563 | 2232 | |
---|
1564 | 2233 | if (debug > 1) |
---|
1565 | 2234 | tvp5150_log_status(sd); |
---|
| 2235 | + |
---|
| 2236 | + pm_runtime_set_active(&c->dev); |
---|
| 2237 | + pm_runtime_enable(&c->dev); |
---|
| 2238 | + pm_runtime_idle(&c->dev); |
---|
| 2239 | + |
---|
1566 | 2240 | return 0; |
---|
1567 | 2241 | |
---|
1568 | 2242 | err: |
---|
.. | .. |
---|
1574 | 2248 | { |
---|
1575 | 2249 | struct v4l2_subdev *sd = i2c_get_clientdata(c); |
---|
1576 | 2250 | struct tvp5150 *decoder = to_tvp5150(sd); |
---|
| 2251 | + unsigned int i; |
---|
1577 | 2252 | |
---|
1578 | 2253 | dev_dbg_lvl(sd->dev, 1, debug, |
---|
1579 | 2254 | "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", |
---|
1580 | 2255 | c->addr << 1); |
---|
1581 | 2256 | |
---|
| 2257 | + for (i = 0; i < decoder->connectors_num; i++) |
---|
| 2258 | + v4l2_fwnode_connector_free(&decoder->connectors[i].base); |
---|
| 2259 | + for (i = 0; i < decoder->connectors_num; i++) { |
---|
| 2260 | + media_device_unregister_entity(&decoder->connectors[i].ent); |
---|
| 2261 | + media_entity_cleanup(&decoder->connectors[i].ent); |
---|
| 2262 | + } |
---|
1582 | 2263 | v4l2_async_unregister_subdev(sd); |
---|
1583 | 2264 | v4l2_ctrl_handler_free(&decoder->hdl); |
---|
| 2265 | + pm_runtime_disable(&c->dev); |
---|
| 2266 | + pm_runtime_set_suspended(&c->dev); |
---|
| 2267 | + |
---|
1584 | 2268 | return 0; |
---|
1585 | 2269 | } |
---|
1586 | 2270 | |
---|
1587 | 2271 | /* ----------------------------------------------------------------------- */ |
---|
| 2272 | + |
---|
| 2273 | +static const struct dev_pm_ops tvp5150_pm_ops = { |
---|
| 2274 | + SET_RUNTIME_PM_OPS(tvp5150_runtime_suspend, |
---|
| 2275 | + tvp5150_runtime_resume, |
---|
| 2276 | + NULL) |
---|
| 2277 | +}; |
---|
1588 | 2278 | |
---|
1589 | 2279 | static const struct i2c_device_id tvp5150_id[] = { |
---|
1590 | 2280 | { "tvp5150", 0 }, |
---|
.. | .. |
---|
1604 | 2294 | .driver = { |
---|
1605 | 2295 | .of_match_table = of_match_ptr(tvp5150_of_match), |
---|
1606 | 2296 | .name = "tvp5150", |
---|
| 2297 | + .pm = &tvp5150_pm_ops, |
---|
1607 | 2298 | }, |
---|
1608 | | - .probe = tvp5150_probe, |
---|
| 2299 | + .probe_new = tvp5150_probe, |
---|
1609 | 2300 | .remove = tvp5150_remove, |
---|
1610 | 2301 | .id_table = tvp5150_id, |
---|
1611 | 2302 | }; |
---|