Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * GS1662 device registration.
0004  *
0005  * Copyright (C) 2015-2016 Nexvision
0006  * Author: Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/spi/spi.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/ctype.h>
0014 #include <linux/err.h>
0015 #include <linux/device.h>
0016 #include <linux/module.h>
0017 
0018 #include <linux/videodev2.h>
0019 #include <media/v4l2-common.h>
0020 #include <media/v4l2-ctrls.h>
0021 #include <media/v4l2-device.h>
0022 #include <media/v4l2-subdev.h>
0023 #include <media/v4l2-dv-timings.h>
0024 #include <linux/v4l2-dv-timings.h>
0025 
0026 #define REG_STATUS          0x04
0027 #define REG_FORCE_FMT           0x06
0028 #define REG_LINES_PER_FRAME     0x12
0029 #define REG_WORDS_PER_LINE      0x13
0030 #define REG_WORDS_PER_ACT_LINE      0x14
0031 #define REG_ACT_LINES_PER_FRAME 0x15
0032 
0033 #define MASK_H_LOCK         0x001
0034 #define MASK_V_LOCK         0x002
0035 #define MASK_STD_LOCK           0x004
0036 #define MASK_FORCE_STD          0x020
0037 #define MASK_STD_STATUS     0x3E0
0038 
0039 #define GS_WIDTH_MIN            720
0040 #define GS_WIDTH_MAX            2048
0041 #define GS_HEIGHT_MIN           487
0042 #define GS_HEIGHT_MAX           1080
0043 #define GS_PIXELCLOCK_MIN       10519200
0044 #define GS_PIXELCLOCK_MAX       74250000
0045 
0046 struct gs {
0047     struct spi_device *pdev;
0048     struct v4l2_subdev sd;
0049     struct v4l2_dv_timings current_timings;
0050     int enabled;
0051 };
0052 
0053 struct gs_reg_fmt {
0054     u16 reg_value;
0055     struct v4l2_dv_timings format;
0056 };
0057 
0058 struct gs_reg_fmt_custom {
0059     u16 reg_value;
0060     __u32 width;
0061     __u32 height;
0062     __u64 pixelclock;
0063     __u32 interlaced;
0064 };
0065 
0066 static const struct spi_device_id gs_id[] = {
0067     { "gs1662", 0 },
0068     { }
0069 };
0070 MODULE_DEVICE_TABLE(spi, gs_id);
0071 
0072 static const struct v4l2_dv_timings fmt_cap[] = {
0073     V4L2_DV_BT_SDI_720X487I60,
0074     V4L2_DV_BT_CEA_720X576P50,
0075     V4L2_DV_BT_CEA_1280X720P24,
0076     V4L2_DV_BT_CEA_1280X720P25,
0077     V4L2_DV_BT_CEA_1280X720P30,
0078     V4L2_DV_BT_CEA_1280X720P50,
0079     V4L2_DV_BT_CEA_1280X720P60,
0080     V4L2_DV_BT_CEA_1920X1080P24,
0081     V4L2_DV_BT_CEA_1920X1080P25,
0082     V4L2_DV_BT_CEA_1920X1080P30,
0083     V4L2_DV_BT_CEA_1920X1080I50,
0084     V4L2_DV_BT_CEA_1920X1080I60,
0085 };
0086 
0087 static const struct gs_reg_fmt reg_fmt[] = {
0088     { 0x00, V4L2_DV_BT_CEA_1280X720P60 },
0089     { 0x01, V4L2_DV_BT_CEA_1280X720P60 },
0090     { 0x02, V4L2_DV_BT_CEA_1280X720P30 },
0091     { 0x03, V4L2_DV_BT_CEA_1280X720P30 },
0092     { 0x04, V4L2_DV_BT_CEA_1280X720P50 },
0093     { 0x05, V4L2_DV_BT_CEA_1280X720P50 },
0094     { 0x06, V4L2_DV_BT_CEA_1280X720P25 },
0095     { 0x07, V4L2_DV_BT_CEA_1280X720P25 },
0096     { 0x08, V4L2_DV_BT_CEA_1280X720P24 },
0097     { 0x09, V4L2_DV_BT_CEA_1280X720P24 },
0098     { 0x0A, V4L2_DV_BT_CEA_1920X1080I60 },
0099     { 0x0B, V4L2_DV_BT_CEA_1920X1080P30 },
0100 
0101     /* Default value: keep this field before 0xC */
0102     { 0x14, V4L2_DV_BT_CEA_1920X1080I50 },
0103     { 0x0C, V4L2_DV_BT_CEA_1920X1080I50 },
0104     { 0x0D, V4L2_DV_BT_CEA_1920X1080P25 },
0105     { 0x0E, V4L2_DV_BT_CEA_1920X1080P25 },
0106     { 0x10, V4L2_DV_BT_CEA_1920X1080P24 },
0107     { 0x12, V4L2_DV_BT_CEA_1920X1080P24 },
0108     { 0x16, V4L2_DV_BT_SDI_720X487I60 },
0109     { 0x19, V4L2_DV_BT_SDI_720X487I60 },
0110     { 0x18, V4L2_DV_BT_CEA_720X576P50 },
0111     { 0x1A, V4L2_DV_BT_CEA_720X576P50 },
0112 
0113     /* Implement following timings before enable it.
0114      * Because of we don't have access to these theoretical timings yet.
0115      * Workaround: use functions to get and set registers for these formats.
0116      */
0117 #if 0
0118     { 0x0F, V4L2_DV_BT_XXX_1920X1080I25 }, /* SMPTE 274M */
0119     { 0x11, V4L2_DV_BT_XXX_1920X1080I24 }, /* SMPTE 274M */
0120     { 0x13, V4L2_DV_BT_XXX_1920X1080I25 }, /* SMPTE 274M */
0121     { 0x15, V4L2_DV_BT_XXX_1920X1035I60 }, /* SMPTE 260M */
0122     { 0x17, V4L2_DV_BT_SDI_720X507I60 }, /* SMPTE 125M */
0123     { 0x1B, V4L2_DV_BT_SDI_720X507I60 }, /* SMPTE 125M */
0124     { 0x1C, V4L2_DV_BT_XXX_2048X1080P25 }, /* SMPTE 428.1M */
0125 #endif
0126 };
0127 
0128 static const struct v4l2_dv_timings_cap gs_timings_cap = {
0129     .type = V4L2_DV_BT_656_1120,
0130     /* keep this initialization for compatibility with GCC < 4.4.6 */
0131     .reserved = { 0 },
0132     V4L2_INIT_BT_TIMINGS(GS_WIDTH_MIN, GS_WIDTH_MAX, GS_HEIGHT_MIN,
0133                  GS_HEIGHT_MAX, GS_PIXELCLOCK_MIN,
0134                  GS_PIXELCLOCK_MAX,
0135                  V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_SDI,
0136                  V4L2_DV_BT_CAP_PROGRESSIVE
0137                  | V4L2_DV_BT_CAP_INTERLACED)
0138 };
0139 
0140 static int gs_read_register(struct spi_device *spi, u16 addr, u16 *value)
0141 {
0142     int ret;
0143     u16 buf_addr = (0x8000 | (0x0FFF & addr));
0144     u16 buf_value = 0;
0145     struct spi_message msg;
0146     struct spi_transfer tx[] = {
0147         {
0148             .tx_buf = &buf_addr,
0149             .len = 2,
0150             .delay = {
0151                 .value = 1,
0152                 .unit = SPI_DELAY_UNIT_USECS
0153             },
0154         }, {
0155             .rx_buf = &buf_value,
0156             .len = 2,
0157             .delay = {
0158                 .value = 1,
0159                 .unit = SPI_DELAY_UNIT_USECS
0160             },
0161         },
0162     };
0163 
0164     spi_message_init(&msg);
0165     spi_message_add_tail(&tx[0], &msg);
0166     spi_message_add_tail(&tx[1], &msg);
0167     ret = spi_sync(spi, &msg);
0168 
0169     *value = buf_value;
0170 
0171     return ret;
0172 }
0173 
0174 static int gs_write_register(struct spi_device *spi, u16 addr, u16 value)
0175 {
0176     int ret;
0177     u16 buf_addr = addr;
0178     u16 buf_value = value;
0179     struct spi_message msg;
0180     struct spi_transfer tx[] = {
0181         {
0182             .tx_buf = &buf_addr,
0183             .len = 2,
0184             .delay = {
0185                 .value = 1,
0186                 .unit = SPI_DELAY_UNIT_USECS
0187             },
0188         }, {
0189             .tx_buf = &buf_value,
0190             .len = 2,
0191             .delay = {
0192                 .value = 1,
0193                 .unit = SPI_DELAY_UNIT_USECS
0194             },
0195         },
0196     };
0197 
0198     spi_message_init(&msg);
0199     spi_message_add_tail(&tx[0], &msg);
0200     spi_message_add_tail(&tx[1], &msg);
0201     ret = spi_sync(spi, &msg);
0202 
0203     return ret;
0204 }
0205 
0206 #ifdef CONFIG_VIDEO_ADV_DEBUG
0207 static int gs_g_register(struct v4l2_subdev *sd,
0208           struct v4l2_dbg_register *reg)
0209 {
0210     struct spi_device *spi = v4l2_get_subdevdata(sd);
0211     u16 val;
0212     int ret;
0213 
0214     ret = gs_read_register(spi, reg->reg & 0xFFFF, &val);
0215     reg->val = val;
0216     reg->size = 2;
0217     return ret;
0218 }
0219 
0220 static int gs_s_register(struct v4l2_subdev *sd,
0221           const struct v4l2_dbg_register *reg)
0222 {
0223     struct spi_device *spi = v4l2_get_subdevdata(sd);
0224 
0225     return gs_write_register(spi, reg->reg & 0xFFFF, reg->val & 0xFFFF);
0226 }
0227 #endif
0228 
0229 static int gs_status_format(u16 status, struct v4l2_dv_timings *timings)
0230 {
0231     int std = (status & MASK_STD_STATUS) >> 5;
0232     int i;
0233 
0234     for (i = 0; i < ARRAY_SIZE(reg_fmt); i++) {
0235         if (reg_fmt[i].reg_value == std) {
0236             *timings = reg_fmt[i].format;
0237             return 0;
0238         }
0239     }
0240 
0241     return -ERANGE;
0242 }
0243 
0244 static u16 get_register_timings(struct v4l2_dv_timings *timings)
0245 {
0246     int i;
0247 
0248     for (i = 0; i < ARRAY_SIZE(reg_fmt); i++) {
0249         if (v4l2_match_dv_timings(timings, &reg_fmt[i].format, 0,
0250                       false))
0251             return reg_fmt[i].reg_value | MASK_FORCE_STD;
0252     }
0253 
0254     return 0x0;
0255 }
0256 
0257 static inline struct gs *to_gs(struct v4l2_subdev *sd)
0258 {
0259     return container_of(sd, struct gs, sd);
0260 }
0261 
0262 static int gs_s_dv_timings(struct v4l2_subdev *sd,
0263             struct v4l2_dv_timings *timings)
0264 {
0265     struct gs *gs = to_gs(sd);
0266     int reg_value;
0267 
0268     reg_value = get_register_timings(timings);
0269     if (reg_value == 0x0)
0270         return -EINVAL;
0271 
0272     gs->current_timings = *timings;
0273     return 0;
0274 }
0275 
0276 static int gs_g_dv_timings(struct v4l2_subdev *sd,
0277             struct v4l2_dv_timings *timings)
0278 {
0279     struct gs *gs = to_gs(sd);
0280 
0281     *timings = gs->current_timings;
0282     return 0;
0283 }
0284 
0285 static int gs_query_dv_timings(struct v4l2_subdev *sd,
0286             struct v4l2_dv_timings *timings)
0287 {
0288     struct gs *gs = to_gs(sd);
0289     struct v4l2_dv_timings fmt;
0290     u16 reg_value, i;
0291     int ret;
0292 
0293     if (gs->enabled)
0294         return -EBUSY;
0295 
0296     /*
0297      * Check if the component detect a line, a frame or something else
0298      * which looks like a video signal activity.
0299      */
0300     for (i = 0; i < 4; i++) {
0301         gs_read_register(gs->pdev, REG_LINES_PER_FRAME + i, &reg_value);
0302         if (reg_value)
0303             break;
0304     }
0305 
0306     /* If no register reports a video signal */
0307     if (i >= 4)
0308         return -ENOLINK;
0309 
0310     gs_read_register(gs->pdev, REG_STATUS, &reg_value);
0311     if (!(reg_value & MASK_H_LOCK) || !(reg_value & MASK_V_LOCK))
0312         return -ENOLCK;
0313     if (!(reg_value & MASK_STD_LOCK))
0314         return -ERANGE;
0315 
0316     ret = gs_status_format(reg_value, &fmt);
0317 
0318     if (ret < 0)
0319         return ret;
0320 
0321     *timings = fmt;
0322     return 0;
0323 }
0324 
0325 static int gs_enum_dv_timings(struct v4l2_subdev *sd,
0326                struct v4l2_enum_dv_timings *timings)
0327 {
0328     if (timings->index >= ARRAY_SIZE(fmt_cap))
0329         return -EINVAL;
0330 
0331     if (timings->pad != 0)
0332         return -EINVAL;
0333 
0334     timings->timings = fmt_cap[timings->index];
0335     return 0;
0336 }
0337 
0338 static int gs_s_stream(struct v4l2_subdev *sd, int enable)
0339 {
0340     struct gs *gs = to_gs(sd);
0341     int reg_value;
0342 
0343     if (gs->enabled == enable)
0344         return 0;
0345 
0346     gs->enabled = enable;
0347 
0348     if (enable) {
0349         /* To force the specific format */
0350         reg_value = get_register_timings(&gs->current_timings);
0351         return gs_write_register(gs->pdev, REG_FORCE_FMT, reg_value);
0352     }
0353 
0354     /* To renable auto-detection mode */
0355     return gs_write_register(gs->pdev, REG_FORCE_FMT, 0x0);
0356 }
0357 
0358 static int gs_g_input_status(struct v4l2_subdev *sd, u32 *status)
0359 {
0360     struct gs *gs = to_gs(sd);
0361     u16 reg_value, i;
0362     int ret;
0363 
0364     /*
0365      * Check if the component detect a line, a frame or something else
0366      * which looks like a video signal activity.
0367      */
0368     for (i = 0; i < 4; i++) {
0369         ret = gs_read_register(gs->pdev,
0370                        REG_LINES_PER_FRAME + i, &reg_value);
0371         if (reg_value)
0372             break;
0373         if (ret) {
0374             *status = V4L2_IN_ST_NO_POWER;
0375             return ret;
0376         }
0377     }
0378 
0379     /* If no register reports a video signal */
0380     if (i >= 4)
0381         *status |= V4L2_IN_ST_NO_SIGNAL;
0382 
0383     ret = gs_read_register(gs->pdev, REG_STATUS, &reg_value);
0384     if (!(reg_value & MASK_H_LOCK))
0385         *status |=  V4L2_IN_ST_NO_H_LOCK;
0386     if (!(reg_value & MASK_V_LOCK))
0387         *status |=  V4L2_IN_ST_NO_V_LOCK;
0388     if (!(reg_value & MASK_STD_LOCK))
0389         *status |=  V4L2_IN_ST_NO_STD_LOCK;
0390 
0391     return ret;
0392 }
0393 
0394 static int gs_dv_timings_cap(struct v4l2_subdev *sd,
0395                  struct v4l2_dv_timings_cap *cap)
0396 {
0397     if (cap->pad != 0)
0398         return -EINVAL;
0399 
0400     *cap = gs_timings_cap;
0401     return 0;
0402 }
0403 
0404 /* V4L2 core operation handlers */
0405 static const struct v4l2_subdev_core_ops gs_core_ops = {
0406 #ifdef CONFIG_VIDEO_ADV_DEBUG
0407     .g_register = gs_g_register,
0408     .s_register = gs_s_register,
0409 #endif
0410 };
0411 
0412 static const struct v4l2_subdev_video_ops gs_video_ops = {
0413     .s_dv_timings = gs_s_dv_timings,
0414     .g_dv_timings = gs_g_dv_timings,
0415     .s_stream = gs_s_stream,
0416     .g_input_status = gs_g_input_status,
0417     .query_dv_timings = gs_query_dv_timings,
0418 };
0419 
0420 static const struct v4l2_subdev_pad_ops gs_pad_ops = {
0421     .enum_dv_timings = gs_enum_dv_timings,
0422     .dv_timings_cap = gs_dv_timings_cap,
0423 };
0424 
0425 /* V4L2 top level operation handlers */
0426 static const struct v4l2_subdev_ops gs_ops = {
0427     .core = &gs_core_ops,
0428     .video = &gs_video_ops,
0429     .pad = &gs_pad_ops,
0430 };
0431 
0432 static int gs_probe(struct spi_device *spi)
0433 {
0434     int ret;
0435     struct gs *gs;
0436     struct v4l2_subdev *sd;
0437 
0438     gs = devm_kzalloc(&spi->dev, sizeof(struct gs), GFP_KERNEL);
0439     if (!gs)
0440         return -ENOMEM;
0441 
0442     gs->pdev = spi;
0443     sd = &gs->sd;
0444 
0445     spi->mode = SPI_MODE_0;
0446     spi->irq = -1;
0447     spi->max_speed_hz = 10000000;
0448     spi->bits_per_word = 16;
0449     ret = spi_setup(spi);
0450     v4l2_spi_subdev_init(sd, spi, &gs_ops);
0451 
0452     gs->current_timings = reg_fmt[0].format;
0453     gs->enabled = 0;
0454 
0455     /* Set H_CONFIG to SMPTE timings */
0456     gs_write_register(spi, 0x0, 0x300);
0457 
0458     return ret;
0459 }
0460 
0461 static void gs_remove(struct spi_device *spi)
0462 {
0463     struct v4l2_subdev *sd = spi_get_drvdata(spi);
0464 
0465     v4l2_device_unregister_subdev(sd);
0466 }
0467 
0468 static struct spi_driver gs_driver = {
0469     .driver = {
0470         .name       = "gs1662",
0471     },
0472 
0473     .probe      = gs_probe,
0474     .remove     = gs_remove,
0475     .id_table   = gs_id,
0476 };
0477 
0478 module_spi_driver(gs_driver);
0479 
0480 MODULE_LICENSE("GPL");
0481 MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@nexvision.fr>");
0482 MODULE_DESCRIPTION("Gennum GS1662 HD/SD-SDI Serializer driver");