0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/module.h>
0015 #include <linux/types.h>
0016 #include <linux/slab.h>
0017 #include <linux/ioctl.h>
0018 #include <linux/uaccess.h>
0019 #include <linux/i2c.h>
0020 #include <linux/videodev2.h>
0021 #include <media/v4l2-device.h>
0022
0023 MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
0024 MODULE_AUTHOR("Dave Perks");
0025 MODULE_LICENSE("GPL");
0026
0027 #define I2C_ADV7175 0xd4
0028 #define I2C_ADV7176 0x54
0029
0030
0031 static int debug;
0032 module_param(debug, int, 0);
0033 MODULE_PARM_DESC(debug, "Debug level (0-1)");
0034
0035
0036
0037 struct adv7175 {
0038 struct v4l2_subdev sd;
0039 v4l2_std_id norm;
0040 int input;
0041 };
0042
0043 static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
0044 {
0045 return container_of(sd, struct adv7175, sd);
0046 }
0047
0048 static char *inputs[] = { "pass_through", "play_back", "color_bar" };
0049
0050 static u32 adv7175_codes[] = {
0051 MEDIA_BUS_FMT_UYVY8_2X8,
0052 MEDIA_BUS_FMT_UYVY8_1X16,
0053 };
0054
0055
0056
0057 static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
0058 {
0059 struct i2c_client *client = v4l2_get_subdevdata(sd);
0060
0061 return i2c_smbus_write_byte_data(client, reg, value);
0062 }
0063
0064 static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
0065 {
0066 struct i2c_client *client = v4l2_get_subdevdata(sd);
0067
0068 return i2c_smbus_read_byte_data(client, reg);
0069 }
0070
0071 static int adv7175_write_block(struct v4l2_subdev *sd,
0072 const u8 *data, unsigned int len)
0073 {
0074 struct i2c_client *client = v4l2_get_subdevdata(sd);
0075 int ret = -1;
0076 u8 reg;
0077
0078
0079
0080 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
0081
0082 u8 block_data[32];
0083 int block_len;
0084
0085 while (len >= 2) {
0086 block_len = 0;
0087 block_data[block_len++] = reg = data[0];
0088 do {
0089 block_data[block_len++] = data[1];
0090 reg++;
0091 len -= 2;
0092 data += 2;
0093 } while (len >= 2 && data[0] == reg && block_len < 32);
0094 ret = i2c_master_send(client, block_data, block_len);
0095 if (ret < 0)
0096 break;
0097 }
0098 } else {
0099
0100 while (len >= 2) {
0101 reg = *data++;
0102 ret = adv7175_write(sd, reg, *data++);
0103 if (ret < 0)
0104 break;
0105 len -= 2;
0106 }
0107 }
0108
0109 return ret;
0110 }
0111
0112 static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
0113 {
0114
0115
0116 if (pass_through)
0117 adv7175_write(sd, 0x02, 0x00);
0118 else
0119 adv7175_write(sd, 0x02, 0x55);
0120
0121 adv7175_write(sd, 0x03, 0x55);
0122 adv7175_write(sd, 0x04, 0x55);
0123 adv7175_write(sd, 0x05, 0x25);
0124 }
0125
0126
0127
0128
0129 #define MR050 0x11
0130 #define MR060 0x14
0131
0132
0133
0134 #define TR0MODE 0x46
0135 #define TR0RST 0x80
0136
0137 #define TR1CAPT 0x80
0138 #define TR1PLAY 0x00
0139
0140 static const unsigned char init_common[] = {
0141
0142 0x00, MR050,
0143 0x01, 0x00,
0144 0x02, 0x0c,
0145 0x03, 0x8c,
0146 0x04, 0x79,
0147 0x05, 0x26,
0148 0x06, 0x40,
0149
0150 0x07, TR0MODE,
0151 0x08, 0x21,
0152 0x09, 0x00,
0153 0x0a, 0x00,
0154 0x0b, 0x00,
0155 0x0c, TR1CAPT,
0156 0x0d, 0x4f,
0157 0x0e, 0x00,
0158 0x0f, 0x00,
0159 0x10, 0x00,
0160 0x11, 0x00,
0161 };
0162
0163 static const unsigned char init_pal[] = {
0164 0x00, MR050,
0165 0x01, 0x00,
0166 0x02, 0x0c,
0167 0x03, 0x8c,
0168 0x04, 0x79,
0169 0x05, 0x26,
0170 0x06, 0x40,
0171 };
0172
0173 static const unsigned char init_ntsc[] = {
0174 0x00, MR060,
0175 0x01, 0x00,
0176 0x02, 0x55,
0177 0x03, 0x55,
0178 0x04, 0x55,
0179 0x05, 0x25,
0180 0x06, 0x1a,
0181 };
0182
0183 static int adv7175_init(struct v4l2_subdev *sd, u32 val)
0184 {
0185
0186 adv7175_write_block(sd, init_common, sizeof(init_common));
0187 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0188 adv7175_write(sd, 0x07, TR0MODE);
0189 return 0;
0190 }
0191
0192 static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
0193 {
0194 struct adv7175 *encoder = to_adv7175(sd);
0195
0196 if (std & V4L2_STD_NTSC) {
0197 adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
0198 if (encoder->input == 0)
0199 adv7175_write(sd, 0x0d, 0x4f);
0200 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0201 adv7175_write(sd, 0x07, TR0MODE);
0202 } else if (std & V4L2_STD_PAL) {
0203 adv7175_write_block(sd, init_pal, sizeof(init_pal));
0204 if (encoder->input == 0)
0205 adv7175_write(sd, 0x0d, 0x4f);
0206 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0207 adv7175_write(sd, 0x07, TR0MODE);
0208 } else if (std & V4L2_STD_SECAM) {
0209
0210
0211
0212
0213
0214
0215 adv7175_write_block(sd, init_pal, sizeof(init_pal));
0216 if (encoder->input == 0)
0217 adv7175_write(sd, 0x0d, 0x49);
0218 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0219 adv7175_write(sd, 0x07, TR0MODE);
0220 } else {
0221 v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
0222 (unsigned long long)std);
0223 return -EINVAL;
0224 }
0225 v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
0226 encoder->norm = std;
0227 return 0;
0228 }
0229
0230 static int adv7175_s_routing(struct v4l2_subdev *sd,
0231 u32 input, u32 output, u32 config)
0232 {
0233 struct adv7175 *encoder = to_adv7175(sd);
0234
0235
0236
0237
0238
0239 switch (input) {
0240 case 0:
0241 adv7175_write(sd, 0x01, 0x00);
0242
0243 if (encoder->norm & V4L2_STD_NTSC)
0244 set_subcarrier_freq(sd, 1);
0245
0246 adv7175_write(sd, 0x0c, TR1CAPT);
0247 if (encoder->norm & V4L2_STD_SECAM)
0248 adv7175_write(sd, 0x0d, 0x49);
0249 else
0250 adv7175_write(sd, 0x0d, 0x4f);
0251 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0252 adv7175_write(sd, 0x07, TR0MODE);
0253
0254 break;
0255
0256 case 1:
0257 adv7175_write(sd, 0x01, 0x00);
0258
0259 if (encoder->norm & V4L2_STD_NTSC)
0260 set_subcarrier_freq(sd, 0);
0261
0262 adv7175_write(sd, 0x0c, TR1PLAY);
0263 adv7175_write(sd, 0x0d, 0x49);
0264 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0265 adv7175_write(sd, 0x07, TR0MODE);
0266
0267 break;
0268
0269 case 2:
0270 adv7175_write(sd, 0x01, 0x80);
0271
0272 if (encoder->norm & V4L2_STD_NTSC)
0273 set_subcarrier_freq(sd, 0);
0274
0275 adv7175_write(sd, 0x0d, 0x49);
0276 adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0277 adv7175_write(sd, 0x07, TR0MODE);
0278
0279 break;
0280
0281 default:
0282 v4l2_dbg(1, debug, sd, "illegal input: %d\n", input);
0283 return -EINVAL;
0284 }
0285 v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[input]);
0286 encoder->input = input;
0287 return 0;
0288 }
0289
0290 static int adv7175_enum_mbus_code(struct v4l2_subdev *sd,
0291 struct v4l2_subdev_state *sd_state,
0292 struct v4l2_subdev_mbus_code_enum *code)
0293 {
0294 if (code->pad || code->index >= ARRAY_SIZE(adv7175_codes))
0295 return -EINVAL;
0296
0297 code->code = adv7175_codes[code->index];
0298 return 0;
0299 }
0300
0301 static int adv7175_get_fmt(struct v4l2_subdev *sd,
0302 struct v4l2_subdev_state *sd_state,
0303 struct v4l2_subdev_format *format)
0304 {
0305 struct v4l2_mbus_framefmt *mf = &format->format;
0306 u8 val = adv7175_read(sd, 0x7);
0307
0308 if (format->pad)
0309 return -EINVAL;
0310
0311 if ((val & 0x40) == (1 << 6))
0312 mf->code = MEDIA_BUS_FMT_UYVY8_1X16;
0313 else
0314 mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
0315
0316 mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
0317 mf->width = 0;
0318 mf->height = 0;
0319 mf->field = V4L2_FIELD_ANY;
0320
0321 return 0;
0322 }
0323
0324 static int adv7175_set_fmt(struct v4l2_subdev *sd,
0325 struct v4l2_subdev_state *sd_state,
0326 struct v4l2_subdev_format *format)
0327 {
0328 struct v4l2_mbus_framefmt *mf = &format->format;
0329 u8 val = adv7175_read(sd, 0x7);
0330 int ret = 0;
0331
0332 if (format->pad)
0333 return -EINVAL;
0334
0335 switch (mf->code) {
0336 case MEDIA_BUS_FMT_UYVY8_2X8:
0337 val &= ~0x40;
0338 break;
0339
0340 case MEDIA_BUS_FMT_UYVY8_1X16:
0341 val |= 0x40;
0342 break;
0343
0344 default:
0345 v4l2_dbg(1, debug, sd,
0346 "illegal v4l2_mbus_framefmt code: %d\n", mf->code);
0347 return -EINVAL;
0348 }
0349
0350 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
0351 ret = adv7175_write(sd, 0x7, val);
0352
0353 return ret;
0354 }
0355
0356 static int adv7175_s_power(struct v4l2_subdev *sd, int on)
0357 {
0358 if (on)
0359 adv7175_write(sd, 0x01, 0x00);
0360 else
0361 adv7175_write(sd, 0x01, 0x78);
0362
0363 return 0;
0364 }
0365
0366
0367
0368 static const struct v4l2_subdev_core_ops adv7175_core_ops = {
0369 .init = adv7175_init,
0370 .s_power = adv7175_s_power,
0371 };
0372
0373 static const struct v4l2_subdev_video_ops adv7175_video_ops = {
0374 .s_std_output = adv7175_s_std_output,
0375 .s_routing = adv7175_s_routing,
0376 };
0377
0378 static const struct v4l2_subdev_pad_ops adv7175_pad_ops = {
0379 .enum_mbus_code = adv7175_enum_mbus_code,
0380 .get_fmt = adv7175_get_fmt,
0381 .set_fmt = adv7175_set_fmt,
0382 };
0383
0384 static const struct v4l2_subdev_ops adv7175_ops = {
0385 .core = &adv7175_core_ops,
0386 .video = &adv7175_video_ops,
0387 .pad = &adv7175_pad_ops,
0388 };
0389
0390
0391
0392 static int adv7175_probe(struct i2c_client *client,
0393 const struct i2c_device_id *id)
0394 {
0395 int i;
0396 struct adv7175 *encoder;
0397 struct v4l2_subdev *sd;
0398
0399
0400 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0401 return -ENODEV;
0402
0403 v4l_info(client, "chip found @ 0x%x (%s)\n",
0404 client->addr << 1, client->adapter->name);
0405
0406 encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
0407 if (encoder == NULL)
0408 return -ENOMEM;
0409 sd = &encoder->sd;
0410 v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
0411 encoder->norm = V4L2_STD_NTSC;
0412 encoder->input = 0;
0413
0414 i = adv7175_write_block(sd, init_common, sizeof(init_common));
0415 if (i >= 0) {
0416 i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
0417 i = adv7175_write(sd, 0x07, TR0MODE);
0418 i = adv7175_read(sd, 0x12);
0419 v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
0420 }
0421 if (i < 0)
0422 v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
0423 return 0;
0424 }
0425
0426 static int adv7175_remove(struct i2c_client *client)
0427 {
0428 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0429
0430 v4l2_device_unregister_subdev(sd);
0431 return 0;
0432 }
0433
0434
0435
0436 static const struct i2c_device_id adv7175_id[] = {
0437 { "adv7175", 0 },
0438 { "adv7176", 0 },
0439 { }
0440 };
0441 MODULE_DEVICE_TABLE(i2c, adv7175_id);
0442
0443 static struct i2c_driver adv7175_driver = {
0444 .driver = {
0445 .name = "adv7175",
0446 },
0447 .probe = adv7175_probe,
0448 .remove = adv7175_remove,
0449 .id_table = adv7175_id,
0450 };
0451
0452 module_i2c_driver(adv7175_driver);