1 /* 2 * saa7110 - Philips SAA7110(A) video decoder driver 3 * 4 * Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl> 5 * 6 * Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net> 7 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> 8 * - some corrections for Pinnacle Systems Inc. DC10plus card. 9 * 10 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net> 11 * - moved over to linux>=2.4.x i2c protocol (1/1/2003) 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 */ 23 24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/types.h> 27 #include <linux/delay.h> 28 #include <linux/slab.h> 29 #include <linux/wait.h> 30 #include <linux/uaccess.h> 31 #include <linux/i2c.h> 32 #include <linux/videodev2.h> 33 #include <media/v4l2-device.h> 34 #include <media/v4l2-ctrls.h> 35 36 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); 37 MODULE_AUTHOR("Pauline Middelink"); 38 MODULE_LICENSE("GPL"); 39 40 41 static int debug; 42 module_param(debug, int, 0); 43 MODULE_PARM_DESC(debug, "Debug level (0-1)"); 44 45 #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ 46 #define SAA7110_MAX_OUTPUT 1 /* 1 YUV */ 47 48 #define SAA7110_NR_REG 0x35 49 50 struct saa7110 { 51 struct v4l2_subdev sd; 52 struct v4l2_ctrl_handler hdl; 53 u8 reg[SAA7110_NR_REG]; 54 55 v4l2_std_id norm; 56 int input; 57 int enable; 58 59 wait_queue_head_t wq; 60 }; 61 62 static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd) 63 { 64 return container_of(sd, struct saa7110, sd); 65 } 66 67 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) 68 { 69 return &container_of(ctrl->handler, struct saa7110, hdl)->sd; 70 } 71 72 /* ----------------------------------------------------------------------- */ 73 /* I2C support functions */ 74 /* ----------------------------------------------------------------------- */ 75 76 static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value) 77 { 78 struct i2c_client *client = v4l2_get_subdevdata(sd); 79 struct saa7110 *decoder = to_saa7110(sd); 80 81 decoder->reg[reg] = value; 82 return i2c_smbus_write_byte_data(client, reg, value); 83 } 84 85 static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len) 86 { 87 struct i2c_client *client = v4l2_get_subdevdata(sd); 88 struct saa7110 *decoder = to_saa7110(sd); 89 int ret = -1; 90 u8 reg = *data; /* first register to write to */ 91 92 /* Sanity check */ 93 if (reg + (len - 1) > SAA7110_NR_REG) 94 return ret; 95 96 /* the saa7110 has an autoincrement function, use it if 97 * the adapter understands raw I2C */ 98 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 99 ret = i2c_master_send(client, data, len); 100 101 /* Cache the written data */ 102 memcpy(decoder->reg + reg, data + 1, len - 1); 103 } else { 104 for (++data, --len; len; len--) { 105 ret = saa7110_write(sd, reg++, *data++); 106 if (ret < 0) 107 break; 108 } 109 } 110 111 return ret; 112 } 113 114 static inline int saa7110_read(struct v4l2_subdev *sd) 115 { 116 struct i2c_client *client = v4l2_get_subdevdata(sd); 117 118 return i2c_smbus_read_byte(client); 119 } 120 121 /* ----------------------------------------------------------------------- */ 122 /* SAA7110 functions */ 123 /* ----------------------------------------------------------------------- */ 124 125 #define FRESP_06H_COMPST 0x03 /*0x13*/ 126 #define FRESP_06H_SVIDEO 0x83 /*0xC0*/ 127 128 129 static int saa7110_selmux(struct v4l2_subdev *sd, int chan) 130 { 131 static const unsigned char modes[9][8] = { 132 /* mode 0 */ 133 {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03, 134 0x44, 0x75, 0x16}, 135 /* mode 1 */ 136 {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03, 137 0x44, 0x75, 0x16}, 138 /* mode 2 */ 139 {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03, 140 0x60, 0xB5, 0x05}, 141 /* mode 3 */ 142 {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03, 143 0x60, 0xB5, 0x05}, 144 /* mode 4 */ 145 {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83, 146 0x60, 0xB5, 0x03}, 147 /* mode 5 */ 148 {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83, 149 0x60, 0xB5, 0x03}, 150 /* mode 6 */ 151 {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3, 152 0x44, 0x75, 0x12}, 153 /* mode 7 */ 154 {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13, 155 0x60, 0xB5, 0x14}, 156 /* mode 8 */ 157 {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23, 158 0x44, 0x75, 0x21} 159 }; 160 struct saa7110 *decoder = to_saa7110(sd); 161 const unsigned char *ptr = modes[chan]; 162 163 saa7110_write(sd, 0x06, ptr[0]); /* Luminance control */ 164 saa7110_write(sd, 0x20, ptr[1]); /* Analog Control #1 */ 165 saa7110_write(sd, 0x21, ptr[2]); /* Analog Control #2 */ 166 saa7110_write(sd, 0x22, ptr[3]); /* Mixer Control #1 */ 167 saa7110_write(sd, 0x2C, ptr[4]); /* Mixer Control #2 */ 168 saa7110_write(sd, 0x30, ptr[5]); /* ADCs gain control */ 169 saa7110_write(sd, 0x31, ptr[6]); /* Mixer Control #3 */ 170 saa7110_write(sd, 0x21, ptr[7]); /* Analog Control #2 */ 171 decoder->input = chan; 172 173 return 0; 174 } 175 176 static const unsigned char initseq[1 + SAA7110_NR_REG] = { 177 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00, 178 /* 0x08 */ 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90, 179 /* 0x10 */ 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA, 180 /* 0x18 */ 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 /* 0x20 */ 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F, 182 /* 0x28 */ 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C, 183 /* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02 184 }; 185 186 static v4l2_std_id determine_norm(struct v4l2_subdev *sd) 187 { 188 DEFINE_WAIT(wait); 189 struct saa7110 *decoder = to_saa7110(sd); 190 int status; 191 192 /* mode changed, start automatic detection */ 193 saa7110_write_block(sd, initseq, sizeof(initseq)); 194 saa7110_selmux(sd, decoder->input); 195 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); 196 schedule_timeout(msecs_to_jiffies(250)); 197 finish_wait(&decoder->wq, &wait); 198 status = saa7110_read(sd); 199 if (status & 0x40) { 200 v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status); 201 return V4L2_STD_UNKNOWN; 202 } 203 if ((status & 3) == 0) { 204 saa7110_write(sd, 0x06, 0x83); 205 if (status & 0x20) { 206 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status); 207 /*saa7110_write(sd,0x2E,0x81);*/ 208 return V4L2_STD_NTSC; 209 } 210 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status); 211 /*saa7110_write(sd,0x2E,0x9A);*/ 212 return V4L2_STD_PAL; 213 } 214 /*saa7110_write(sd,0x06,0x03);*/ 215 if (status & 0x20) { /* 60Hz */ 216 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status); 217 saa7110_write(sd, 0x0D, 0x86); 218 saa7110_write(sd, 0x0F, 0x50); 219 saa7110_write(sd, 0x11, 0x2C); 220 /*saa7110_write(sd,0x2E,0x81);*/ 221 return V4L2_STD_NTSC; 222 } 223 224 /* 50Hz -> PAL/SECAM */ 225 saa7110_write(sd, 0x0D, 0x86); 226 saa7110_write(sd, 0x0F, 0x10); 227 saa7110_write(sd, 0x11, 0x59); 228 /*saa7110_write(sd,0x2E,0x9A);*/ 229 230 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE); 231 schedule_timeout(msecs_to_jiffies(250)); 232 finish_wait(&decoder->wq, &wait); 233 234 status = saa7110_read(sd); 235 if ((status & 0x03) == 0x01) { 236 v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status); 237 saa7110_write(sd, 0x0D, 0x87); 238 return V4L2_STD_SECAM; 239 } 240 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status); 241 return V4L2_STD_PAL; 242 } 243 244 static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus) 245 { 246 struct saa7110 *decoder = to_saa7110(sd); 247 int res = V4L2_IN_ST_NO_SIGNAL; 248 int status = saa7110_read(sd); 249 250 v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n", 251 status, (unsigned long long)decoder->norm); 252 if (!(status & 0x40)) 253 res = 0; 254 if (!(status & 0x03)) 255 res |= V4L2_IN_ST_NO_COLOR; 256 257 *pstatus = res; 258 return 0; 259 } 260 261 static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 262 { 263 *std &= determine_norm(sd); 264 return 0; 265 } 266 267 static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 268 { 269 struct saa7110 *decoder = to_saa7110(sd); 270 271 if (decoder->norm != std) { 272 decoder->norm = std; 273 /*saa7110_write(sd, 0x06, 0x03);*/ 274 if (std & V4L2_STD_NTSC) { 275 saa7110_write(sd, 0x0D, 0x86); 276 saa7110_write(sd, 0x0F, 0x50); 277 saa7110_write(sd, 0x11, 0x2C); 278 /*saa7110_write(sd, 0x2E, 0x81);*/ 279 v4l2_dbg(1, debug, sd, "switched to NTSC\n"); 280 } else if (std & V4L2_STD_PAL) { 281 saa7110_write(sd, 0x0D, 0x86); 282 saa7110_write(sd, 0x0F, 0x10); 283 saa7110_write(sd, 0x11, 0x59); 284 /*saa7110_write(sd, 0x2E, 0x9A);*/ 285 v4l2_dbg(1, debug, sd, "switched to PAL\n"); 286 } else if (std & V4L2_STD_SECAM) { 287 saa7110_write(sd, 0x0D, 0x87); 288 saa7110_write(sd, 0x0F, 0x10); 289 saa7110_write(sd, 0x11, 0x59); 290 /*saa7110_write(sd, 0x2E, 0x9A);*/ 291 v4l2_dbg(1, debug, sd, "switched to SECAM\n"); 292 } else { 293 return -EINVAL; 294 } 295 } 296 return 0; 297 } 298 299 static int saa7110_s_routing(struct v4l2_subdev *sd, 300 u32 input, u32 output, u32 config) 301 { 302 struct saa7110 *decoder = to_saa7110(sd); 303 304 if (input >= SAA7110_MAX_INPUT) { 305 v4l2_dbg(1, debug, sd, "input=%d not available\n", input); 306 return -EINVAL; 307 } 308 if (decoder->input != input) { 309 saa7110_selmux(sd, input); 310 v4l2_dbg(1, debug, sd, "switched to input=%d\n", input); 311 } 312 return 0; 313 } 314 315 static int saa7110_s_stream(struct v4l2_subdev *sd, int enable) 316 { 317 struct saa7110 *decoder = to_saa7110(sd); 318 319 if (decoder->enable != enable) { 320 decoder->enable = enable; 321 saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80); 322 v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off"); 323 } 324 return 0; 325 } 326 327 static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl) 328 { 329 struct v4l2_subdev *sd = to_sd(ctrl); 330 331 switch (ctrl->id) { 332 case V4L2_CID_BRIGHTNESS: 333 saa7110_write(sd, 0x19, ctrl->val); 334 break; 335 case V4L2_CID_CONTRAST: 336 saa7110_write(sd, 0x13, ctrl->val); 337 break; 338 case V4L2_CID_SATURATION: 339 saa7110_write(sd, 0x12, ctrl->val); 340 break; 341 case V4L2_CID_HUE: 342 saa7110_write(sd, 0x07, ctrl->val); 343 break; 344 default: 345 return -EINVAL; 346 } 347 return 0; 348 } 349 350 /* ----------------------------------------------------------------------- */ 351 352 static const struct v4l2_ctrl_ops saa7110_ctrl_ops = { 353 .s_ctrl = saa7110_s_ctrl, 354 }; 355 356 static const struct v4l2_subdev_video_ops saa7110_video_ops = { 357 .s_std = saa7110_s_std, 358 .s_routing = saa7110_s_routing, 359 .s_stream = saa7110_s_stream, 360 .querystd = saa7110_querystd, 361 .g_input_status = saa7110_g_input_status, 362 }; 363 364 static const struct v4l2_subdev_ops saa7110_ops = { 365 .video = &saa7110_video_ops, 366 }; 367 368 /* ----------------------------------------------------------------------- */ 369 370 static int saa7110_probe(struct i2c_client *client, 371 const struct i2c_device_id *id) 372 { 373 struct saa7110 *decoder; 374 struct v4l2_subdev *sd; 375 int rv; 376 377 /* Check if the adapter supports the needed features */ 378 if (!i2c_check_functionality(client->adapter, 379 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 380 return -ENODEV; 381 382 v4l_info(client, "chip found @ 0x%x (%s)\n", 383 client->addr << 1, client->adapter->name); 384 385 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL); 386 if (!decoder) 387 return -ENOMEM; 388 sd = &decoder->sd; 389 v4l2_i2c_subdev_init(sd, client, &saa7110_ops); 390 decoder->norm = V4L2_STD_PAL; 391 decoder->input = 0; 392 decoder->enable = 1; 393 v4l2_ctrl_handler_init(&decoder->hdl, 2); 394 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops, 395 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 396 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops, 397 V4L2_CID_CONTRAST, 0, 127, 1, 64); 398 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops, 399 V4L2_CID_SATURATION, 0, 127, 1, 64); 400 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops, 401 V4L2_CID_HUE, -128, 127, 1, 0); 402 sd->ctrl_handler = &decoder->hdl; 403 if (decoder->hdl.error) { 404 int err = decoder->hdl.error; 405 406 v4l2_ctrl_handler_free(&decoder->hdl); 407 return err; 408 } 409 v4l2_ctrl_handler_setup(&decoder->hdl); 410 411 init_waitqueue_head(&decoder->wq); 412 413 rv = saa7110_write_block(sd, initseq, sizeof(initseq)); 414 if (rv < 0) { 415 v4l2_dbg(1, debug, sd, "init status %d\n", rv); 416 } else { 417 int ver, status; 418 saa7110_write(sd, 0x21, 0x10); 419 saa7110_write(sd, 0x0e, 0x18); 420 saa7110_write(sd, 0x0D, 0x04); 421 ver = saa7110_read(sd); 422 saa7110_write(sd, 0x0D, 0x06); 423 /*mdelay(150);*/ 424 status = saa7110_read(sd); 425 v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n", 426 ver, status); 427 saa7110_write(sd, 0x0D, 0x86); 428 saa7110_write(sd, 0x0F, 0x10); 429 saa7110_write(sd, 0x11, 0x59); 430 /*saa7110_write(sd, 0x2E, 0x9A);*/ 431 } 432 433 /*saa7110_selmux(sd,0);*/ 434 /*determine_norm(sd);*/ 435 /* setup and implicit mode 0 select has been performed */ 436 437 return 0; 438 } 439 440 static int saa7110_remove(struct i2c_client *client) 441 { 442 struct v4l2_subdev *sd = i2c_get_clientdata(client); 443 struct saa7110 *decoder = to_saa7110(sd); 444 445 v4l2_device_unregister_subdev(sd); 446 v4l2_ctrl_handler_free(&decoder->hdl); 447 return 0; 448 } 449 450 /* ----------------------------------------------------------------------- */ 451 452 static const struct i2c_device_id saa7110_id[] = { 453 { "saa7110", 0 }, 454 { } 455 }; 456 MODULE_DEVICE_TABLE(i2c, saa7110_id); 457 458 static struct i2c_driver saa7110_driver = { 459 .driver = { 460 .name = "saa7110", 461 }, 462 .probe = saa7110_probe, 463 .remove = saa7110_remove, 464 .id_table = saa7110_id, 465 }; 466 467 module_i2c_driver(saa7110_driver); 468