1/* 2 dpc7146.c - v4l2 driver for the dpc7146 demonstration board 3 4 Copyright (C) 2000-2003 Michael Hunold <michael@mihu.de> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#define DEBUG_VARIABLE debug 22 23#include <media/saa7146_vv.h> 24#include <linux/video_decoder.h> /* for saa7111a */ 25 26#define I2C_SAA7111A 0x24 27 28/* All unused bytes are reserverd. */ 29#define SAA711X_CHIP_VERSION 0x00 30#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02 31#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03 32#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04 33#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05 34#define SAA711X_HORIZONTAL_SYNC_START 0x06 35#define SAA711X_HORIZONTAL_SYNC_STOP 0x07 36#define SAA711X_SYNC_CONTROL 0x08 37#define SAA711X_LUMINANCE_CONTROL 0x09 38#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A 39#define SAA711X_LUMINANCE_CONTRAST 0x0B 40#define SAA711X_CHROMA_SATURATION 0x0C 41#define SAA711X_CHROMA_HUE_CONTROL 0x0D 42#define SAA711X_CHROMA_CONTROL 0x0E 43#define SAA711X_FORMAT_DELAY_CONTROL 0x10 44#define SAA711X_OUTPUT_CONTROL_1 0x11 45#define SAA711X_OUTPUT_CONTROL_2 0x12 46#define SAA711X_OUTPUT_CONTROL_3 0x13 47#define SAA711X_V_GATE_1_START 0x15 48#define SAA711X_V_GATE_1_STOP 0x16 49#define SAA711X_V_GATE_1_MSB 0x17 50#define SAA711X_TEXT_SLICER_STATUS 0x1A 51#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B 52#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C 53#define SAA711X_STATUS_BYTE 0x1F 54 55#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) 56 57static int debug = 0; 58module_param(debug, int, 0); 59MODULE_PARM_DESC(debug, "debug verbosity"); 60 61static int dpc_num = 0; 62 63#define DPC_INPUTS 2 64static struct v4l2_input dpc_inputs[DPC_INPUTS] = { 65 { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 66 { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, 67}; 68 69#define DPC_AUDIOS 0 70 71static struct saa7146_extension_ioctls ioctls[] = { 72 { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, 73 { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, 74 { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, 75 { VIDIOC_S_STD, SAA7146_AFTER }, 76 { 0, 0 } 77}; 78 79struct dpc 80{ 81 struct video_device *video_dev; 82 struct video_device *vbi_dev; 83 84 struct i2c_adapter i2c_adapter; 85 struct i2c_client *saa7111a; 86 87 int cur_input; /* current input */ 88}; 89 90static int dpc_probe(struct saa7146_dev* dev) 91{ 92 struct dpc* dpc = NULL; 93 struct i2c_client *client; 94 struct list_head *item; 95 96 dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); 97 if( NULL == dpc ) { 98 printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n"); 99 return -ENOMEM; 100 } 101 102 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); 103 104 dpc->i2c_adapter = (struct i2c_adapter) { 105 .class = I2C_CLASS_TV_ANALOG, 106 .name = "dpc7146", 107 }; 108 saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); 109 if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { 110 DEB_S(("cannot register i2c-device. skipping.\n")); 111 kfree(dpc); 112 return -EFAULT; 113 } 114 115 /* loop through all i2c-devices on the bus and look who is there */ 116 list_for_each(item,&dpc->i2c_adapter.clients) { 117 client = list_entry(item, struct i2c_client, list); 118 if( I2C_SAA7111A == client->addr ) 119 dpc->saa7111a = client; 120 } 121 122 /* check if all devices are present */ 123 if( 0 == dpc->saa7111a ) { 124 DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); 125 i2c_del_adapter(&dpc->i2c_adapter); 126 kfree(dpc); 127 return -ENODEV; 128 } 129 130 /* all devices are present, probe was successful */ 131 DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); 132 133 /* we store the pointer in our private data field */ 134 dev->ext_priv = dpc; 135 136 return 0; 137} 138 139/* bring hardware to a sane state. this has to be done, just in case someone 140 wants to capture from this device before it has been properly initialized. 141 the capture engine would badly fail, because no valid signal arrives on the 142 saa7146, thus leading to timeouts and stuff. */ 143static int dpc_init_done(struct saa7146_dev* dev) 144{ 145 struct dpc* dpc = (struct dpc*)dev->ext_priv; 146 147 DEB_D(("dpc_v4l2.o: dpc_init_done called.\n")); 148 149 /* initialize the helper ics to useful values */ 150 i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11); 151 152 i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0); 153 i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30); 154 i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00); 155 i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00); 156 i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde); 157 i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad); 158 i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8); 159 i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00); 160 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80); 161 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47); 162 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40); 163 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00); 164 i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03); 165 166 i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0); 167 i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c); 168 i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1); 169 i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30); 170 171 i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81); 172 173 return 0; 174} 175 176static struct saa7146_ext_vv vv_data; 177 178/* this function only gets called when the probing was successful */ 179static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 180{ 181 struct dpc* dpc = (struct dpc*)dev->ext_priv; 182 183 DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); 184 185 /* checking for i2c-devices can be omitted here, because we 186 already did this in "dpc_vl42_probe" */ 187 188 saa7146_vv_init(dev,&vv_data); 189 if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) { 190 ERR(("cannot register capture v4l2 device. skipping.\n")); 191 return -1; 192 } 193 194 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ 195 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { 196 if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { 197 ERR(("cannot register vbi v4l2 device. skipping.\n")); 198 } 199 } 200 201 i2c_use_client(dpc->saa7111a); 202 203 printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); 204 dpc_num++; 205 206 /* the rest */ 207 dpc->cur_input = 0; 208 dpc_init_done(dev); 209 210 return 0; 211} 212 213static int dpc_detach(struct saa7146_dev* dev) 214{ 215 struct dpc* dpc = (struct dpc*)dev->ext_priv; 216 217 DEB_EE(("dev:%p\n",dev)); 218 219 i2c_release_client(dpc->saa7111a); 220 221 saa7146_unregister_device(&dpc->video_dev,dev); 222 if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { 223 saa7146_unregister_device(&dpc->vbi_dev,dev); 224 } 225 saa7146_vv_release(dev); 226 227 dpc_num--; 228 229 i2c_del_adapter(&dpc->i2c_adapter); 230 kfree(dpc); 231 return 0; 232} 233 234#ifdef axa 235int dpc_vbi_bypass(struct saa7146_dev* dev) 236{ 237 struct dpc* dpc = (struct dpc*)dev->ext_priv; 238 239 int i = 1; 240 241 /* switch bypass in saa7111a */ 242 if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { 243 printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); 244 return -1; 245 } 246 247 return 0; 248} 249#endif 250 251static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) 252{ 253 struct saa7146_dev *dev = fh->dev; 254 struct dpc* dpc = (struct dpc*)dev->ext_priv; 255/* 256 struct saa7146_vv *vv = dev->vv_data; 257*/ 258 switch(cmd) 259 { 260 case VIDIOC_ENUMINPUT: 261 { 262 struct v4l2_input *i = arg; 263 DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); 264 265 if( i->index < 0 || i->index >= DPC_INPUTS) { 266 return -EINVAL; 267 } 268 269 memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); 270 271 DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); 272 return 0; 273 } 274 case VIDIOC_G_INPUT: 275 { 276 int *input = (int *)arg; 277 *input = dpc->cur_input; 278 279 DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input)); 280 return 0; 281 } 282 case VIDIOC_S_INPUT: 283 { 284 int input = *(int *)arg; 285 286 if (input < 0 || input >= DPC_INPUTS) { 287 return -EINVAL; 288 } 289 290 dpc->cur_input = input; 291 292// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); 293 printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); 294 295 return 0; 296 } 297 default: 298/* 299 DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n")); 300*/ 301 return -ENOIOCTLCMD; 302 } 303 return 0; 304} 305 306static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) 307{ 308 return 0; 309} 310 311static struct saa7146_standard standard[] = { 312 { 313 .name = "PAL", .id = V4L2_STD_PAL, 314 .v_offset = 0x17, .v_field = 288, 315 .h_offset = 0x14, .h_pixels = 680, 316 .v_max_out = 576, .h_max_out = 768, 317 }, { 318 .name = "NTSC", .id = V4L2_STD_NTSC, 319 .v_offset = 0x16, .v_field = 240, 320 .h_offset = 0x06, .h_pixels = 708, 321 .v_max_out = 480, .h_max_out = 640, 322 }, { 323 .name = "SECAM", .id = V4L2_STD_SECAM, 324 .v_offset = 0x14, .v_field = 288, 325 .h_offset = 0x14, .h_pixels = 720, 326 .v_max_out = 576, .h_max_out = 768, 327 } 328}; 329 330static struct saa7146_extension extension; 331 332static struct saa7146_pci_extension_data dpc = { 333 .ext_priv = "Multimedia eXtension Board", 334 .ext = &extension, 335}; 336 337static struct pci_device_id pci_tbl[] = { 338 { 339 .vendor = PCI_VENDOR_ID_PHILIPS, 340 .device = PCI_DEVICE_ID_PHILIPS_SAA7146, 341 .subvendor = 0x0000, 342 .subdevice = 0x0000, 343 .driver_data = (unsigned long)&dpc, 344 }, { 345 .vendor = 0, 346 } 347}; 348 349MODULE_DEVICE_TABLE(pci, pci_tbl); 350 351static struct saa7146_ext_vv vv_data = { 352 .inputs = DPC_INPUTS, 353 .capabilities = V4L2_CAP_VBI_CAPTURE, 354 .stds = &standard[0], 355 .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 356 .std_callback = &std_callback, 357 .ioctls = &ioctls[0], 358 .ioctl = dpc_ioctl, 359}; 360 361static struct saa7146_extension extension = { 362 .name = "dpc7146 demonstration board", 363 .flags = SAA7146_USE_I2C_IRQ, 364 365 .pci_tbl = &pci_tbl[0], 366 .module = THIS_MODULE, 367 368 .probe = dpc_probe, 369 .attach = dpc_attach, 370 .detach = dpc_detach, 371 372 .irq_mask = 0, 373 .irq_func = NULL, 374}; 375 376static int __init dpc_init_module(void) 377{ 378 if( 0 != saa7146_register_extension(&extension)) { 379 DEB_S(("failed to register extension.\n")); 380 return -ENODEV; 381 } 382 383 return 0; 384} 385 386static void __exit dpc_cleanup_module(void) 387{ 388 saa7146_unregister_extension(&extension); 389} 390 391module_init(dpc_init_module); 392module_exit(dpc_cleanup_module); 393 394MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'"); 395MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 396MODULE_LICENSE("GPL"); 397