Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  bt819 - BT819A VideoStream Decoder (Rockwell Part)
0004  *
0005  * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
0006  * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
0007  *
0008  * Modifications for LML33/DC10plus unified driver
0009  * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
0010  *
0011  * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
0012  *    - moved over to linux>=2.4.x i2c protocol (9/9/2002)
0013  *
0014  * This code was modify/ported from the saa7111 driver written
0015  * by Dave Perks.
0016  */
0017 
0018 #include <linux/module.h>
0019 #include <linux/types.h>
0020 #include <linux/ioctl.h>
0021 #include <linux/delay.h>
0022 #include <linux/i2c.h>
0023 #include <linux/videodev2.h>
0024 #include <linux/slab.h>
0025 #include <media/v4l2-device.h>
0026 #include <media/v4l2-ctrls.h>
0027 #include <media/i2c/bt819.h>
0028 
0029 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
0030 MODULE_AUTHOR("Mike Bernson & Dave Perks");
0031 MODULE_LICENSE("GPL");
0032 
0033 static int debug;
0034 module_param(debug, int, 0);
0035 MODULE_PARM_DESC(debug, "Debug level (0-1)");
0036 
0037 
0038 /* ----------------------------------------------------------------------- */
0039 
0040 struct bt819 {
0041     struct v4l2_subdev sd;
0042     struct v4l2_ctrl_handler hdl;
0043     unsigned char reg[32];
0044 
0045     v4l2_std_id norm;
0046     int input;
0047     int enable;
0048 };
0049 
0050 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
0051 {
0052     return container_of(sd, struct bt819, sd);
0053 }
0054 
0055 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
0056 {
0057     return &container_of(ctrl->handler, struct bt819, hdl)->sd;
0058 }
0059 
0060 struct timing {
0061     int hactive;
0062     int hdelay;
0063     int vactive;
0064     int vdelay;
0065     int hscale;
0066     int vscale;
0067 };
0068 
0069 /* for values, see the bt819 datasheet */
0070 static struct timing timing_data[] = {
0071     {864 - 24, 20, 625 - 2, 1, 0x0504, 0x0000},
0072     {858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
0073 };
0074 
0075 /* ----------------------------------------------------------------------- */
0076 
0077 static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
0078 {
0079     struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
0080 
0081     decoder->reg[reg] = value;
0082     return i2c_smbus_write_byte_data(client, reg, value);
0083 }
0084 
0085 static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
0086 {
0087     return bt819_write(decoder, reg,
0088         (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
0089 }
0090 
0091 static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
0092 {
0093     struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
0094     int ret = -1;
0095     u8 reg;
0096 
0097     /* the bt819 has an autoincrement function, use it if
0098      * the adapter understands raw I2C */
0099     if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
0100         /* do raw I2C, not smbus compatible */
0101         u8 block_data[32];
0102         int block_len;
0103 
0104         while (len >= 2) {
0105             block_len = 0;
0106             block_data[block_len++] = reg = data[0];
0107             do {
0108                 block_data[block_len++] =
0109                     decoder->reg[reg++] = data[1];
0110                 len -= 2;
0111                 data += 2;
0112             } while (len >= 2 && data[0] == reg && block_len < 32);
0113             ret = i2c_master_send(client, block_data, block_len);
0114             if (ret < 0)
0115                 break;
0116         }
0117     } else {
0118         /* do some slow I2C emulation kind of thing */
0119         while (len >= 2) {
0120             reg = *data++;
0121             ret = bt819_write(decoder, reg, *data++);
0122             if (ret < 0)
0123                 break;
0124             len -= 2;
0125         }
0126     }
0127 
0128     return ret;
0129 }
0130 
0131 static inline int bt819_read(struct bt819 *decoder, u8 reg)
0132 {
0133     struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
0134 
0135     return i2c_smbus_read_byte_data(client, reg);
0136 }
0137 
0138 static int bt819_init(struct v4l2_subdev *sd)
0139 {
0140     static unsigned char init[] = {
0141         /*0x1f, 0x00,*/     /* Reset */
0142         0x01, 0x59, /* 0x01 input format */
0143         0x02, 0x00, /* 0x02 temporal decimation */
0144         0x03, 0x12, /* 0x03 Cropping msb */
0145         0x04, 0x16, /* 0x04 Vertical Delay, lsb */
0146         0x05, 0xe0, /* 0x05 Vertical Active lsb */
0147         0x06, 0x80, /* 0x06 Horizontal Delay lsb */
0148         0x07, 0xd0, /* 0x07 Horizontal Active lsb */
0149         0x08, 0x00, /* 0x08 Horizontal Scaling msb */
0150         0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
0151         0x0a, 0x00, /* 0x0a Brightness control */
0152         0x0b, 0x30, /* 0x0b Miscellaneous control */
0153         0x0c, 0xd8, /* 0x0c Luma Gain lsb */
0154         0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
0155         0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
0156         0x0f, 0x00, /* 0x0f Hue control */
0157         0x12, 0x04, /* 0x12 Output Format */
0158         0x13, 0x20, /* 0x13 Vertical Scaling msb 0x00
0159                        chroma comb OFF, line drop scaling, interlace scaling
0160                        BUG? Why does turning the chroma comb on screw up color?
0161                        Bug in the bt819 stepping on my board?
0162                     */
0163         0x14, 0x00, /* 0x14 Vertical Scaling lsb */
0164         0x16, 0x07, /* 0x16 Video Timing Polarity
0165                        ACTIVE=active low
0166                        FIELD: high=odd,
0167                        vreset=active high,
0168                        hreset=active high */
0169         0x18, 0x68, /* 0x18 AGC Delay */
0170         0x19, 0x5d, /* 0x19 Burst Gate Delay */
0171         0x1a, 0x80, /* 0x1a ADC Interface */
0172     };
0173 
0174     struct bt819 *decoder = to_bt819(sd);
0175     struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
0176 
0177     init[0x03 * 2 - 1] =
0178         (((timing->vdelay >> 8) & 0x03) << 6) |
0179         (((timing->vactive >> 8) & 0x03) << 4) |
0180         (((timing->hdelay >> 8) & 0x03) << 2) |
0181         ((timing->hactive >> 8) & 0x03);
0182     init[0x04 * 2 - 1] = timing->vdelay & 0xff;
0183     init[0x05 * 2 - 1] = timing->vactive & 0xff;
0184     init[0x06 * 2 - 1] = timing->hdelay & 0xff;
0185     init[0x07 * 2 - 1] = timing->hactive & 0xff;
0186     init[0x08 * 2 - 1] = timing->hscale >> 8;
0187     init[0x09 * 2 - 1] = timing->hscale & 0xff;
0188     /* 0x15 in array is address 0x19 */
0189     init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93;  /* Chroma burst delay */
0190     /* reset */
0191     bt819_write(decoder, 0x1f, 0x00);
0192     mdelay(1);
0193 
0194     /* init */
0195     return bt819_write_block(decoder, init, sizeof(init));
0196 }
0197 
0198 /* ----------------------------------------------------------------------- */
0199 
0200 static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
0201 {
0202     struct bt819 *decoder = to_bt819(sd);
0203     int status = bt819_read(decoder, 0x00);
0204     int res = V4L2_IN_ST_NO_SIGNAL;
0205     v4l2_std_id std = pstd ? *pstd : V4L2_STD_ALL;
0206 
0207     if ((status & 0x80))
0208         res = 0;
0209     else
0210         std = V4L2_STD_UNKNOWN;
0211 
0212     if ((status & 0x10))
0213         std &= V4L2_STD_PAL;
0214     else
0215         std &= V4L2_STD_NTSC;
0216     if (pstd)
0217         *pstd = std;
0218     if (pstatus)
0219         *pstatus = res;
0220 
0221     v4l2_dbg(1, debug, sd, "get status %x\n", status);
0222     return 0;
0223 }
0224 
0225 static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
0226 {
0227     return bt819_status(sd, NULL, std);
0228 }
0229 
0230 static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
0231 {
0232     return bt819_status(sd, status, NULL);
0233 }
0234 
0235 static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
0236 {
0237     struct bt819 *decoder = to_bt819(sd);
0238     struct timing *timing = NULL;
0239 
0240     v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
0241 
0242     if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
0243         v4l2_err(sd, "no notify found!\n");
0244 
0245     if (std & V4L2_STD_NTSC) {
0246         v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
0247         bt819_setbit(decoder, 0x01, 0, 1);
0248         bt819_setbit(decoder, 0x01, 1, 0);
0249         bt819_setbit(decoder, 0x01, 5, 0);
0250         bt819_write(decoder, 0x18, 0x68);
0251         bt819_write(decoder, 0x19, 0x5d);
0252         /* bt819_setbit(decoder, 0x1a,  5, 1); */
0253         timing = &timing_data[1];
0254     } else if (std & V4L2_STD_PAL) {
0255         v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
0256         bt819_setbit(decoder, 0x01, 0, 1);
0257         bt819_setbit(decoder, 0x01, 1, 1);
0258         bt819_setbit(decoder, 0x01, 5, 1);
0259         bt819_write(decoder, 0x18, 0x7f);
0260         bt819_write(decoder, 0x19, 0x72);
0261         /* bt819_setbit(decoder, 0x1a,  5, 0); */
0262         timing = &timing_data[0];
0263     } else {
0264         v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
0265                 (unsigned long long)std);
0266         return -EINVAL;
0267     }
0268     bt819_write(decoder, 0x03,
0269             (((timing->vdelay >> 8) & 0x03) << 6) |
0270             (((timing->vactive >> 8) & 0x03) << 4) |
0271             (((timing->hdelay >> 8) & 0x03) << 2) |
0272             ((timing->hactive >> 8) & 0x03));
0273     bt819_write(decoder, 0x04, timing->vdelay & 0xff);
0274     bt819_write(decoder, 0x05, timing->vactive & 0xff);
0275     bt819_write(decoder, 0x06, timing->hdelay & 0xff);
0276     bt819_write(decoder, 0x07, timing->hactive & 0xff);
0277     bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
0278     bt819_write(decoder, 0x09, timing->hscale & 0xff);
0279     decoder->norm = std;
0280     v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
0281     return 0;
0282 }
0283 
0284 static int bt819_s_routing(struct v4l2_subdev *sd,
0285                u32 input, u32 output, u32 config)
0286 {
0287     struct bt819 *decoder = to_bt819(sd);
0288 
0289     v4l2_dbg(1, debug, sd, "set input %x\n", input);
0290 
0291     if (input > 7)
0292         return -EINVAL;
0293 
0294     if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
0295         v4l2_err(sd, "no notify found!\n");
0296 
0297     if (decoder->input != input) {
0298         v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, NULL);
0299         decoder->input = input;
0300         /* select mode */
0301         if (decoder->input == 0) {
0302             bt819_setbit(decoder, 0x0b, 6, 0);
0303             bt819_setbit(decoder, 0x1a, 1, 1);
0304         } else {
0305             bt819_setbit(decoder, 0x0b, 6, 1);
0306             bt819_setbit(decoder, 0x1a, 1, 0);
0307         }
0308         v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, NULL);
0309     }
0310     return 0;
0311 }
0312 
0313 static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
0314 {
0315     struct bt819 *decoder = to_bt819(sd);
0316 
0317     v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
0318 
0319     if (decoder->enable != enable) {
0320         decoder->enable = enable;
0321         bt819_setbit(decoder, 0x16, 7, !enable);
0322     }
0323     return 0;
0324 }
0325 
0326 static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
0327 {
0328     struct v4l2_subdev *sd = to_sd(ctrl);
0329     struct bt819 *decoder = to_bt819(sd);
0330     int temp;
0331 
0332     switch (ctrl->id) {
0333     case V4L2_CID_BRIGHTNESS:
0334         bt819_write(decoder, 0x0a, ctrl->val);
0335         break;
0336 
0337     case V4L2_CID_CONTRAST:
0338         bt819_write(decoder, 0x0c, ctrl->val & 0xff);
0339         bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
0340         break;
0341 
0342     case V4L2_CID_SATURATION:
0343         bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
0344         bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
0345 
0346         /* Ratio between U gain and V gain must stay the same as
0347            the ratio between the default U and V gain values. */
0348         temp = (ctrl->val * 180) / 254;
0349         bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
0350         bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
0351         break;
0352 
0353     case V4L2_CID_HUE:
0354         bt819_write(decoder, 0x0f, ctrl->val);
0355         break;
0356 
0357     default:
0358         return -EINVAL;
0359     }
0360     return 0;
0361 }
0362 
0363 /* ----------------------------------------------------------------------- */
0364 
0365 static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
0366     .s_ctrl = bt819_s_ctrl,
0367 };
0368 
0369 static const struct v4l2_subdev_video_ops bt819_video_ops = {
0370     .s_std = bt819_s_std,
0371     .s_routing = bt819_s_routing,
0372     .s_stream = bt819_s_stream,
0373     .querystd = bt819_querystd,
0374     .g_input_status = bt819_g_input_status,
0375 };
0376 
0377 static const struct v4l2_subdev_ops bt819_ops = {
0378     .video = &bt819_video_ops,
0379 };
0380 
0381 /* ----------------------------------------------------------------------- */
0382 
0383 static int bt819_probe(struct i2c_client *client,
0384             const struct i2c_device_id *id)
0385 {
0386     int i, ver;
0387     struct bt819 *decoder;
0388     struct v4l2_subdev *sd;
0389     const char *name;
0390 
0391     /* Check if the adapter supports the needed features */
0392     if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0393         return -ENODEV;
0394 
0395     decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
0396     if (decoder == NULL)
0397         return -ENOMEM;
0398     sd = &decoder->sd;
0399     v4l2_i2c_subdev_init(sd, client, &bt819_ops);
0400 
0401     ver = bt819_read(decoder, 0x17);
0402     switch (ver & 0xf0) {
0403     case 0x70:
0404         name = "bt819a";
0405         break;
0406     case 0x60:
0407         name = "bt817a";
0408         break;
0409     case 0x20:
0410         name = "bt815a";
0411         break;
0412     default:
0413         v4l2_dbg(1, debug, sd,
0414             "unknown chip version 0x%02x\n", ver);
0415         return -ENODEV;
0416     }
0417 
0418     v4l_info(client, "%s found @ 0x%x (%s)\n", name,
0419             client->addr << 1, client->adapter->name);
0420 
0421     decoder->norm = V4L2_STD_NTSC;
0422     decoder->input = 0;
0423     decoder->enable = 1;
0424 
0425     i = bt819_init(sd);
0426     if (i < 0)
0427         v4l2_dbg(1, debug, sd, "init status %d\n", i);
0428 
0429     v4l2_ctrl_handler_init(&decoder->hdl, 4);
0430     v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
0431             V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
0432     v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
0433             V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
0434     v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
0435             V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
0436     v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
0437             V4L2_CID_HUE, -128, 127, 1, 0);
0438     sd->ctrl_handler = &decoder->hdl;
0439     if (decoder->hdl.error) {
0440         int err = decoder->hdl.error;
0441 
0442         v4l2_ctrl_handler_free(&decoder->hdl);
0443         return err;
0444     }
0445     v4l2_ctrl_handler_setup(&decoder->hdl);
0446     return 0;
0447 }
0448 
0449 static int bt819_remove(struct i2c_client *client)
0450 {
0451     struct v4l2_subdev *sd = i2c_get_clientdata(client);
0452     struct bt819 *decoder = to_bt819(sd);
0453 
0454     v4l2_device_unregister_subdev(sd);
0455     v4l2_ctrl_handler_free(&decoder->hdl);
0456     return 0;
0457 }
0458 
0459 /* ----------------------------------------------------------------------- */
0460 
0461 static const struct i2c_device_id bt819_id[] = {
0462     { "bt819a", 0 },
0463     { "bt817a", 0 },
0464     { "bt815a", 0 },
0465     { }
0466 };
0467 MODULE_DEVICE_TABLE(i2c, bt819_id);
0468 
0469 static struct i2c_driver bt819_driver = {
0470     .driver = {
0471         .name   = "bt819",
0472     },
0473     .probe      = bt819_probe,
0474     .remove     = bt819_remove,
0475     .id_table   = bt819_id,
0476 };
0477 
0478 module_i2c_driver(bt819_driver);