0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/types.h>
0018 #include <linux/delay.h>
0019 #include <linux/slab.h>
0020 #include <linux/wait.h>
0021 #include <linux/uaccess.h>
0022 #include <linux/i2c.h>
0023 #include <linux/videodev2.h>
0024 #include <media/v4l2-device.h>
0025 #include <media/v4l2-ctrls.h>
0026
0027 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
0028 MODULE_AUTHOR("Pauline Middelink");
0029 MODULE_LICENSE("GPL");
0030
0031
0032 static int debug;
0033 module_param(debug, int, 0);
0034 MODULE_PARM_DESC(debug, "Debug level (0-1)");
0035
0036 #define SAA7110_MAX_INPUT 9
0037 #define SAA7110_MAX_OUTPUT 1
0038
0039 #define SAA7110_NR_REG 0x35
0040
0041 struct saa7110 {
0042 struct v4l2_subdev sd;
0043 struct v4l2_ctrl_handler hdl;
0044 u8 reg[SAA7110_NR_REG];
0045
0046 v4l2_std_id norm;
0047 int input;
0048 int enable;
0049
0050 wait_queue_head_t wq;
0051 };
0052
0053 static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
0054 {
0055 return container_of(sd, struct saa7110, sd);
0056 }
0057
0058 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
0059 {
0060 return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
0061 }
0062
0063
0064
0065
0066
0067 static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
0068 {
0069 struct i2c_client *client = v4l2_get_subdevdata(sd);
0070 struct saa7110 *decoder = to_saa7110(sd);
0071
0072 decoder->reg[reg] = value;
0073 return i2c_smbus_write_byte_data(client, reg, value);
0074 }
0075
0076 static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
0077 {
0078 struct i2c_client *client = v4l2_get_subdevdata(sd);
0079 struct saa7110 *decoder = to_saa7110(sd);
0080 int ret = -1;
0081 u8 reg = *data;
0082
0083
0084 if (reg + (len - 1) > SAA7110_NR_REG)
0085 return ret;
0086
0087
0088
0089 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
0090 ret = i2c_master_send(client, data, len);
0091
0092
0093 memcpy(decoder->reg + reg, data + 1, len - 1);
0094 } else {
0095 for (++data, --len; len; len--) {
0096 ret = saa7110_write(sd, reg++, *data++);
0097 if (ret < 0)
0098 break;
0099 }
0100 }
0101
0102 return ret;
0103 }
0104
0105 static inline int saa7110_read(struct v4l2_subdev *sd)
0106 {
0107 struct i2c_client *client = v4l2_get_subdevdata(sd);
0108
0109 return i2c_smbus_read_byte(client);
0110 }
0111
0112
0113
0114
0115
0116 #define FRESP_06H_COMPST 0x03
0117 #define FRESP_06H_SVIDEO 0x83
0118
0119
0120 static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
0121 {
0122 static const unsigned char modes[9][8] = {
0123
0124 {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
0125 0x44, 0x75, 0x16},
0126
0127 {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
0128 0x44, 0x75, 0x16},
0129
0130 {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
0131 0x60, 0xB5, 0x05},
0132
0133 {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
0134 0x60, 0xB5, 0x05},
0135
0136 {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
0137 0x60, 0xB5, 0x03},
0138
0139 {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
0140 0x60, 0xB5, 0x03},
0141
0142 {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
0143 0x44, 0x75, 0x12},
0144
0145 {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
0146 0x60, 0xB5, 0x14},
0147
0148 {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
0149 0x44, 0x75, 0x21}
0150 };
0151 struct saa7110 *decoder = to_saa7110(sd);
0152 const unsigned char *ptr = modes[chan];
0153
0154 saa7110_write(sd, 0x06, ptr[0]);
0155 saa7110_write(sd, 0x20, ptr[1]);
0156 saa7110_write(sd, 0x21, ptr[2]);
0157 saa7110_write(sd, 0x22, ptr[3]);
0158 saa7110_write(sd, 0x2C, ptr[4]);
0159 saa7110_write(sd, 0x30, ptr[5]);
0160 saa7110_write(sd, 0x31, ptr[6]);
0161 saa7110_write(sd, 0x21, ptr[7]);
0162 decoder->input = chan;
0163
0164 return 0;
0165 }
0166
0167 static const unsigned char initseq[1 + SAA7110_NR_REG] = {
0168 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
0169 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
0170 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
0171 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0172 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
0173 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
0174 0x44, 0x71, 0x02, 0x8C, 0x02
0175 };
0176
0177 static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
0178 {
0179 DEFINE_WAIT(wait);
0180 struct saa7110 *decoder = to_saa7110(sd);
0181 int status;
0182
0183
0184 saa7110_write_block(sd, initseq, sizeof(initseq));
0185 saa7110_selmux(sd, decoder->input);
0186 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
0187 schedule_timeout(msecs_to_jiffies(250));
0188 finish_wait(&decoder->wq, &wait);
0189 status = saa7110_read(sd);
0190 if (status & 0x40) {
0191 v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
0192 return V4L2_STD_UNKNOWN;
0193 }
0194 if ((status & 3) == 0) {
0195 saa7110_write(sd, 0x06, 0x83);
0196 if (status & 0x20) {
0197 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
0198
0199 return V4L2_STD_NTSC;
0200 }
0201 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
0202
0203 return V4L2_STD_PAL;
0204 }
0205
0206 if (status & 0x20) {
0207 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
0208 saa7110_write(sd, 0x0D, 0x86);
0209 saa7110_write(sd, 0x0F, 0x50);
0210 saa7110_write(sd, 0x11, 0x2C);
0211
0212 return V4L2_STD_NTSC;
0213 }
0214
0215
0216 saa7110_write(sd, 0x0D, 0x86);
0217 saa7110_write(sd, 0x0F, 0x10);
0218 saa7110_write(sd, 0x11, 0x59);
0219
0220
0221 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
0222 schedule_timeout(msecs_to_jiffies(250));
0223 finish_wait(&decoder->wq, &wait);
0224
0225 status = saa7110_read(sd);
0226 if ((status & 0x03) == 0x01) {
0227 v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
0228 saa7110_write(sd, 0x0D, 0x87);
0229 return V4L2_STD_SECAM;
0230 }
0231 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
0232 return V4L2_STD_PAL;
0233 }
0234
0235 static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
0236 {
0237 struct saa7110 *decoder = to_saa7110(sd);
0238 int res = V4L2_IN_ST_NO_SIGNAL;
0239 int status = saa7110_read(sd);
0240
0241 v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
0242 status, (unsigned long long)decoder->norm);
0243 if (!(status & 0x40))
0244 res = 0;
0245 if (!(status & 0x03))
0246 res |= V4L2_IN_ST_NO_COLOR;
0247
0248 *pstatus = res;
0249 return 0;
0250 }
0251
0252 static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
0253 {
0254 *std &= determine_norm(sd);
0255 return 0;
0256 }
0257
0258 static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
0259 {
0260 struct saa7110 *decoder = to_saa7110(sd);
0261
0262 if (decoder->norm != std) {
0263 decoder->norm = std;
0264
0265 if (std & V4L2_STD_NTSC) {
0266 saa7110_write(sd, 0x0D, 0x86);
0267 saa7110_write(sd, 0x0F, 0x50);
0268 saa7110_write(sd, 0x11, 0x2C);
0269
0270 v4l2_dbg(1, debug, sd, "switched to NTSC\n");
0271 } else if (std & V4L2_STD_PAL) {
0272 saa7110_write(sd, 0x0D, 0x86);
0273 saa7110_write(sd, 0x0F, 0x10);
0274 saa7110_write(sd, 0x11, 0x59);
0275
0276 v4l2_dbg(1, debug, sd, "switched to PAL\n");
0277 } else if (std & V4L2_STD_SECAM) {
0278 saa7110_write(sd, 0x0D, 0x87);
0279 saa7110_write(sd, 0x0F, 0x10);
0280 saa7110_write(sd, 0x11, 0x59);
0281
0282 v4l2_dbg(1, debug, sd, "switched to SECAM\n");
0283 } else {
0284 return -EINVAL;
0285 }
0286 }
0287 return 0;
0288 }
0289
0290 static int saa7110_s_routing(struct v4l2_subdev *sd,
0291 u32 input, u32 output, u32 config)
0292 {
0293 struct saa7110 *decoder = to_saa7110(sd);
0294
0295 if (input >= SAA7110_MAX_INPUT) {
0296 v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
0297 return -EINVAL;
0298 }
0299 if (decoder->input != input) {
0300 saa7110_selmux(sd, input);
0301 v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
0302 }
0303 return 0;
0304 }
0305
0306 static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
0307 {
0308 struct saa7110 *decoder = to_saa7110(sd);
0309
0310 if (decoder->enable != enable) {
0311 decoder->enable = enable;
0312 saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
0313 v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
0314 }
0315 return 0;
0316 }
0317
0318 static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
0319 {
0320 struct v4l2_subdev *sd = to_sd(ctrl);
0321
0322 switch (ctrl->id) {
0323 case V4L2_CID_BRIGHTNESS:
0324 saa7110_write(sd, 0x19, ctrl->val);
0325 break;
0326 case V4L2_CID_CONTRAST:
0327 saa7110_write(sd, 0x13, ctrl->val);
0328 break;
0329 case V4L2_CID_SATURATION:
0330 saa7110_write(sd, 0x12, ctrl->val);
0331 break;
0332 case V4L2_CID_HUE:
0333 saa7110_write(sd, 0x07, ctrl->val);
0334 break;
0335 default:
0336 return -EINVAL;
0337 }
0338 return 0;
0339 }
0340
0341
0342
0343 static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
0344 .s_ctrl = saa7110_s_ctrl,
0345 };
0346
0347 static const struct v4l2_subdev_video_ops saa7110_video_ops = {
0348 .s_std = saa7110_s_std,
0349 .s_routing = saa7110_s_routing,
0350 .s_stream = saa7110_s_stream,
0351 .querystd = saa7110_querystd,
0352 .g_input_status = saa7110_g_input_status,
0353 };
0354
0355 static const struct v4l2_subdev_ops saa7110_ops = {
0356 .video = &saa7110_video_ops,
0357 };
0358
0359
0360
0361 static int saa7110_probe(struct i2c_client *client,
0362 const struct i2c_device_id *id)
0363 {
0364 struct saa7110 *decoder;
0365 struct v4l2_subdev *sd;
0366 int rv;
0367
0368
0369 if (!i2c_check_functionality(client->adapter,
0370 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
0371 return -ENODEV;
0372
0373 v4l_info(client, "chip found @ 0x%x (%s)\n",
0374 client->addr << 1, client->adapter->name);
0375
0376 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
0377 if (!decoder)
0378 return -ENOMEM;
0379 sd = &decoder->sd;
0380 v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
0381 decoder->norm = V4L2_STD_PAL;
0382 decoder->input = 0;
0383 decoder->enable = 1;
0384 v4l2_ctrl_handler_init(&decoder->hdl, 2);
0385 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
0386 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
0387 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
0388 V4L2_CID_CONTRAST, 0, 127, 1, 64);
0389 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
0390 V4L2_CID_SATURATION, 0, 127, 1, 64);
0391 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
0392 V4L2_CID_HUE, -128, 127, 1, 0);
0393 sd->ctrl_handler = &decoder->hdl;
0394 if (decoder->hdl.error) {
0395 int err = decoder->hdl.error;
0396
0397 v4l2_ctrl_handler_free(&decoder->hdl);
0398 return err;
0399 }
0400 v4l2_ctrl_handler_setup(&decoder->hdl);
0401
0402 init_waitqueue_head(&decoder->wq);
0403
0404 rv = saa7110_write_block(sd, initseq, sizeof(initseq));
0405 if (rv < 0) {
0406 v4l2_dbg(1, debug, sd, "init status %d\n", rv);
0407 } else {
0408 int ver, status;
0409 saa7110_write(sd, 0x21, 0x10);
0410 saa7110_write(sd, 0x0e, 0x18);
0411 saa7110_write(sd, 0x0D, 0x04);
0412 ver = saa7110_read(sd);
0413 saa7110_write(sd, 0x0D, 0x06);
0414
0415 status = saa7110_read(sd);
0416 v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
0417 ver, status);
0418 saa7110_write(sd, 0x0D, 0x86);
0419 saa7110_write(sd, 0x0F, 0x10);
0420 saa7110_write(sd, 0x11, 0x59);
0421
0422 }
0423
0424
0425
0426
0427
0428 return 0;
0429 }
0430
0431 static int saa7110_remove(struct i2c_client *client)
0432 {
0433 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0434 struct saa7110 *decoder = to_saa7110(sd);
0435
0436 v4l2_device_unregister_subdev(sd);
0437 v4l2_ctrl_handler_free(&decoder->hdl);
0438 return 0;
0439 }
0440
0441
0442
0443 static const struct i2c_device_id saa7110_id[] = {
0444 { "saa7110", 0 },
0445 { }
0446 };
0447 MODULE_DEVICE_TABLE(i2c, saa7110_id);
0448
0449 static struct i2c_driver saa7110_driver = {
0450 .driver = {
0451 .name = "saa7110",
0452 },
0453 .probe = saa7110_probe,
0454 .remove = saa7110_remove,
0455 .id_table = saa7110_id,
0456 };
0457
0458 module_i2c_driver(saa7110_driver);