1/* 2 * Driver for the SAA5246A or SAA5281 Teletext (=Videotext) decoder chips from 3 * Philips. 4 * 5 * Only capturing of Teletext pages is tested. The videotext chips also have a 6 * TV output but my hardware doesn't use it. For this reason this driver does 7 * not support changing any TV display settings. 8 * 9 * Copyright (C) 2004 Michael Geng <linux@MichaelGeng.de> 10 * 11 * Derived from 12 * 13 * saa5249 driver 14 * Copyright (C) 1998 Richard Guenther 15 * <richard.guenther@student.uni-tuebingen.de> 16 * 17 * with changes by 18 * Alan Cox <Alan.Cox@linux.org> 19 * 20 * and 21 * 22 * vtx.c 23 * Copyright (C) 1994-97 Martin Buck <martin-2.buck@student.uni-ulm.de> 24 * 25 * This program is free software; you can redistribute it and/or modify 26 * it under the terms of the GNU General Public License as published by 27 * the Free Software Foundation; either version 2 of the License, or 28 * (at your option) any later version. 29 * 30 * This program is distributed in the hope that it will be useful, 31 * but WITHOUT ANY WARRANTY; without even the implied warranty of 32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 * GNU General Public License for more details. 34 * 35 * You should have received a copy of the GNU General Public License 36 * along with this program; if not, write to the Free Software 37 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 38 * USA. 39 */ 40 41#include <linux/module.h> 42#include <linux/kernel.h> 43#include <linux/mm.h> 44#include <linux/init.h> 45#include <linux/i2c.h> 46#include <linux/videotext.h> 47#include <linux/videodev.h> 48#include <media/v4l2-common.h> 49#include <linux/mutex.h> 50 51#include "saa5246a.h" 52 53MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); 54MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); 55MODULE_LICENSE("GPL"); 56 57struct saa5246a_device 58{ 59 u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; 60 int is_searching[NUM_DAUS]; 61 struct i2c_client *client; 62 struct mutex lock; 63}; 64 65static struct video_device saa_template; /* Declared near bottom */ 66 67/* Addresses to scan */ 68static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END }; 69I2C_CLIENT_INSMOD; 70 71static struct i2c_client client_template; 72 73static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) 74{ 75 int pgbuf; 76 int err; 77 struct i2c_client *client; 78 struct video_device *vd; 79 struct saa5246a_device *t; 80 81 printk(KERN_INFO "saa5246a: teletext chip found.\n"); 82 client=kmalloc(sizeof(*client), GFP_KERNEL); 83 if(client==NULL) 84 return -ENOMEM; 85 client_template.adapter = adap; 86 client_template.addr = addr; 87 memcpy(client, &client_template, sizeof(*client)); 88 t = kzalloc(sizeof(*t), GFP_KERNEL); 89 if(t==NULL) 90 { 91 kfree(client); 92 return -ENOMEM; 93 } 94 strlcpy(client->name, IF_NAME, I2C_NAME_SIZE); 95 mutex_init(&t->lock); 96 97 /* 98 * Now create a video4linux device 99 */ 100 101 vd = video_device_alloc(); 102 if(vd==NULL) 103 { 104 kfree(t); 105 kfree(client); 106 return -ENOMEM; 107 } 108 i2c_set_clientdata(client, vd); 109 memcpy(vd, &saa_template, sizeof(*vd)); 110 111 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) 112 { 113 memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); 114 t->is_searching[pgbuf] = false; 115 } 116 vd->priv=t; 117 118 119 /* 120 * Register it 121 */ 122 123 if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0) 124 { 125 kfree(t); 126 kfree(client); 127 video_device_release(vd); 128 return err; 129 } 130 t->client = client; 131 i2c_attach_client(client); 132 return 0; 133} 134 135/* 136 * We do most of the hard work when we become a device on the i2c. 137 */ 138static int saa5246a_probe(struct i2c_adapter *adap) 139{ 140 if (adap->class & I2C_CLASS_TV_ANALOG) 141 return i2c_probe(adap, &addr_data, saa5246a_attach); 142 return 0; 143} 144 145static int saa5246a_detach(struct i2c_client *client) 146{ 147 struct video_device *vd = i2c_get_clientdata(client); 148 i2c_detach_client(client); 149 video_unregister_device(vd); 150 kfree(vd->priv); 151 kfree(client); 152 return 0; 153} 154 155/* 156 * I2C interfaces 157 */ 158 159static struct i2c_driver i2c_driver_videotext = 160{ 161 .driver = { 162 .name = IF_NAME, /* name */ 163 }, 164 .id = I2C_DRIVERID_SAA5249, /* in i2c.h */ 165 .attach_adapter = saa5246a_probe, 166 .detach_client = saa5246a_detach, 167}; 168 169static struct i2c_client client_template = { 170 .driver = &i2c_driver_videotext, 171 .name = "(unset)", 172}; 173 174static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) 175{ 176 char buf[64]; 177 178 buf[0] = reg; 179 memcpy(buf+1, data, count); 180 181 if(i2c_master_send(t->client, buf, count+1)==count+1) 182 return 0; 183 return -1; 184} 185 186static int i2c_senddata(struct saa5246a_device *t, ...) 187{ 188 unsigned char buf[64]; 189 int v; 190 int ct=0; 191 va_list argp; 192 va_start(argp,t); 193 194 while((v=va_arg(argp,int))!=-1) 195 buf[ct++]=v; 196 return i2c_sendbuf(t, buf[0], ct-1, buf+1); 197} 198 199/* Get count number of bytes from I�C-device at address adr, store them in buf. 200 * Start & stop handshaking is done by this routine, ack will be sent after the 201 * last byte to inhibit further sending of data. If uaccess is 'true', data is 202 * written to user-space with put_user. Returns -1 if I�C-device didn't send 203 * acknowledge, 0 otherwise 204 */ 205static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf) 206{ 207 if(i2c_master_recv(t->client, buf, count)!=count) 208 return -1; 209 return 0; 210} 211 212/* When a page is found then the not FOUND bit in one of the status registers 213 * of the SAA5264A chip is cleared. Unfortunately this bit is not set 214 * automatically when a new page is requested. Instead this function must be 215 * called after a page has been requested. 216 * 217 * Return value: 0 if successful 218 */ 219static int saa5246a_clear_found_bit(struct saa5246a_device *t, 220 unsigned char dau_no) 221{ 222 unsigned char row_25_column_8; 223 224 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 225 226 dau_no | 227 R8_DO_NOT_CLEAR_MEMORY, 228 229 R9_CURSER_ROW_25, 230 231 R10_CURSER_COLUMN_8, 232 233 COMMAND_END) || 234 i2c_getdata(t, 1, &row_25_column_8)) 235 { 236 return -EIO; 237 } 238 row_25_column_8 |= ROW25_COLUMN8_PAGE_NOT_FOUND; 239 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 240 241 dau_no | 242 R8_DO_NOT_CLEAR_MEMORY, 243 244 R9_CURSER_ROW_25, 245 246 R10_CURSER_COLUMN_8, 247 248 row_25_column_8, 249 250 COMMAND_END)) 251 { 252 return -EIO; 253 } 254 255 return 0; 256} 257 258/* Requests one videotext page as described in req. The fields of req are 259 * checked and an error is returned if something is invalid. 260 * 261 * Return value: 0 if successful 262 */ 263static int saa5246a_request_page(struct saa5246a_device *t, 264 vtx_pagereq_t *req) 265{ 266 if (req->pagemask < 0 || req->pagemask >= PGMASK_MAX) 267 return -EINVAL; 268 if (req->pagemask & PGMASK_PAGE) 269 if (req->page < 0 || req->page > PAGE_MAX) 270 return -EINVAL; 271 if (req->pagemask & PGMASK_HOUR) 272 if (req->hour < 0 || req->hour > HOUR_MAX) 273 return -EINVAL; 274 if (req->pagemask & PGMASK_MINUTE) 275 if (req->minute < 0 || req->minute > MINUTE_MAX) 276 return -EINVAL; 277 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) 278 return -EINVAL; 279 280 if (i2c_senddata(t, SAA5246A_REGISTER_R2, 281 282 R2_IN_R3_SELECT_PAGE_HUNDREDS | 283 req->pgbuf << 4 | 284 R2_BANK_0 | 285 R2_HAMMING_CHECK_OFF, 286 287 HUNDREDS_OF_PAGE(req->page) | 288 R3_HOLD_PAGE | 289 (req->pagemask & PG_HUND ? 290 R3_PAGE_HUNDREDS_DO_CARE : 291 R3_PAGE_HUNDREDS_DO_NOT_CARE), 292 293 TENS_OF_PAGE(req->page) | 294 (req->pagemask & PG_TEN ? 295 R3_PAGE_TENS_DO_CARE : 296 R3_PAGE_TENS_DO_NOT_CARE), 297 298 UNITS_OF_PAGE(req->page) | 299 (req->pagemask & PG_UNIT ? 300 R3_PAGE_UNITS_DO_CARE : 301 R3_PAGE_UNITS_DO_NOT_CARE), 302 303 TENS_OF_HOUR(req->hour) | 304 (req->pagemask & HR_TEN ? 305 R3_HOURS_TENS_DO_CARE : 306 R3_HOURS_TENS_DO_NOT_CARE), 307 308 UNITS_OF_HOUR(req->hour) | 309 (req->pagemask & HR_UNIT ? 310 R3_HOURS_UNITS_DO_CARE : 311 R3_HOURS_UNITS_DO_NOT_CARE), 312 313 TENS_OF_MINUTE(req->minute) | 314 (req->pagemask & MIN_TEN ? 315 R3_MINUTES_TENS_DO_CARE : 316 R3_MINUTES_TENS_DO_NOT_CARE), 317 318 UNITS_OF_MINUTE(req->minute) | 319 (req->pagemask & MIN_UNIT ? 320 R3_MINUTES_UNITS_DO_CARE : 321 R3_MINUTES_UNITS_DO_NOT_CARE), 322 323 COMMAND_END) || i2c_senddata(t, SAA5246A_REGISTER_R2, 324 325 R2_IN_R3_SELECT_PAGE_HUNDREDS | 326 req->pgbuf << 4 | 327 R2_BANK_0 | 328 R2_HAMMING_CHECK_OFF, 329 330 HUNDREDS_OF_PAGE(req->page) | 331 R3_UPDATE_PAGE | 332 (req->pagemask & PG_HUND ? 333 R3_PAGE_HUNDREDS_DO_CARE : 334 R3_PAGE_HUNDREDS_DO_NOT_CARE), 335 336 COMMAND_END)) 337 { 338 return -EIO; 339 } 340 341 t->is_searching[req->pgbuf] = true; 342 return 0; 343} 344 345/* This routine decodes the page number from the infobits contained in line 25. 346 * 347 * Parameters: 348 * infobits: must be bits 0 to 9 of column 25 349 * 350 * Return value: page number coded in hexadecimal, i. e. page 123 is coded 0x123 351 */ 352static inline int saa5246a_extract_pagenum_from_infobits( 353 unsigned char infobits[10]) 354{ 355 int page_hundreds, page_tens, page_units; 356 357 page_units = infobits[0] & ROW25_COLUMN0_PAGE_UNITS; 358 page_tens = infobits[1] & ROW25_COLUMN1_PAGE_TENS; 359 page_hundreds = infobits[8] & ROW25_COLUMN8_PAGE_HUNDREDS; 360 361 /* page 0x.. means page 8.. */ 362 if (page_hundreds == 0) 363 page_hundreds = 8; 364 365 return((page_hundreds << 8) | (page_tens << 4) | page_units); 366} 367 368/* Decodes the hour from the infobits contained in line 25. 369 * 370 * Parameters: 371 * infobits: must be bits 0 to 9 of column 25 372 * 373 * Return: hour coded in hexadecimal, i. e. 12h is coded 0x12 374 */ 375static inline int saa5246a_extract_hour_from_infobits( 376 unsigned char infobits[10]) 377{ 378 int hour_tens, hour_units; 379 380 hour_units = infobits[4] & ROW25_COLUMN4_HOUR_UNITS; 381 hour_tens = infobits[5] & ROW25_COLUMN5_HOUR_TENS; 382 383 return((hour_tens << 4) | hour_units); 384} 385 386/* Decodes the minutes from the infobits contained in line 25. 387 * 388 * Parameters: 389 * infobits: must be bits 0 to 9 of column 25 390 * 391 * Return: minutes coded in hexadecimal, i. e. 10min is coded 0x10 392 */ 393static inline int saa5246a_extract_minutes_from_infobits( 394 unsigned char infobits[10]) 395{ 396 int minutes_tens, minutes_units; 397 398 minutes_units = infobits[2] & ROW25_COLUMN2_MINUTES_UNITS; 399 minutes_tens = infobits[3] & ROW25_COLUMN3_MINUTES_TENS; 400 401 return((minutes_tens << 4) | minutes_units); 402} 403 404/* Reads the status bits contained in the first 10 columns of the first line 405 * and extracts the information into info. 406 * 407 * Return value: 0 if successful 408 */ 409static inline int saa5246a_get_status(struct saa5246a_device *t, 410 vtx_pageinfo_t *info, unsigned char dau_no) 411{ 412 unsigned char infobits[10]; 413 int column; 414 415 if (dau_no >= NUM_DAUS) 416 return -EINVAL; 417 418 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 419 420 dau_no | 421 R8_DO_NOT_CLEAR_MEMORY, 422 423 R9_CURSER_ROW_25, 424 425 R10_CURSER_COLUMN_0, 426 427 COMMAND_END) || 428 i2c_getdata(t, 10, infobits)) 429 { 430 return -EIO; 431 } 432 433 info->pagenum = saa5246a_extract_pagenum_from_infobits(infobits); 434 info->hour = saa5246a_extract_hour_from_infobits(infobits); 435 info->minute = saa5246a_extract_minutes_from_infobits(infobits); 436 info->charset = ((infobits[7] & ROW25_COLUMN7_CHARACTER_SET) >> 1); 437 info->delete = !!(infobits[3] & ROW25_COLUMN3_DELETE_PAGE); 438 info->headline = !!(infobits[5] & ROW25_COLUMN5_INSERT_HEADLINE); 439 info->subtitle = !!(infobits[5] & ROW25_COLUMN5_INSERT_SUBTITLE); 440 info->supp_header = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_HEADER); 441 info->update = !!(infobits[6] & ROW25_COLUMN6_UPDATE_PAGE); 442 info->inter_seq = !!(infobits[6] & ROW25_COLUMN6_INTERRUPTED_SEQUENCE); 443 info->dis_disp = !!(infobits[6] & ROW25_COLUMN6_SUPPRESS_DISPLAY); 444 info->serial = !!(infobits[7] & ROW25_COLUMN7_SERIAL_MODE); 445 info->notfound = !!(infobits[8] & ROW25_COLUMN8_PAGE_NOT_FOUND); 446 info->pblf = !!(infobits[9] & ROW25_COLUMN9_PAGE_BEING_LOOKED_FOR); 447 info->hamming = 0; 448 for (column = 0; column <= 7; column++) { 449 if (infobits[column] & ROW25_COLUMN0_TO_7_HAMMING_ERROR) { 450 info->hamming = 1; 451 break; 452 } 453 } 454 if (!info->hamming && !info->notfound) 455 t->is_searching[dau_no] = false; 456 return 0; 457} 458 459/* Reads 1 videotext page buffer of the SAA5246A. 460 * 461 * req is used both as input and as output. It contains information which part 462 * must be read. The videotext page is copied into req->buffer. 463 * 464 * Return value: 0 if successful 465 */ 466static inline int saa5246a_get_page(struct saa5246a_device *t, 467 vtx_pagereq_t *req) 468{ 469 int start, end, size; 470 char *buf; 471 int err; 472 473 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || 474 req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE) 475 return -EINVAL; 476 477 buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL); 478 if (!buf) 479 return -ENOMEM; 480 481 /* Read "normal" part of page */ 482 err = -EIO; 483 484 end = min(req->end, VTX_PAGESIZE - 1); 485 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 486 req->pgbuf | R8_DO_NOT_CLEAR_MEMORY, 487 ROW(req->start), COLUMN(req->start), COMMAND_END)) 488 goto out; 489 if (i2c_getdata(t, end - req->start + 1, buf)) 490 goto out; 491 err = -EFAULT; 492 if (copy_to_user(req->buffer, buf, end - req->start + 1)) 493 goto out; 494 495 /* Always get the time from buffer 4, since this stupid SAA5246A only 496 * updates the currently displayed buffer... 497 */ 498 if (REQ_CONTAINS_TIME(req)) { 499 start = max(req->start, POS_TIME_START); 500 end = min(req->end, POS_TIME_END); 501 size = end - start + 1; 502 err = -EINVAL; 503 if (size < 0) 504 goto out; 505 err = -EIO; 506 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 507 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, 508 R9_CURSER_ROW_0, start, COMMAND_END)) 509 goto out; 510 if (i2c_getdata(t, size, buf)) 511 goto out; 512 err = -EFAULT; 513 if (copy_to_user(req->buffer + start - req->start, buf, size)) 514 goto out; 515 } 516 /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */ 517 if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) { 518 start = max(req->start, POS_HEADER_START); 519 end = min(req->end, POS_HEADER_END); 520 size = end - start + 1; 521 err = -EINVAL; 522 if (size < 0) 523 goto out; 524 err = -EIO; 525 if (i2c_senddata(t, SAA5246A_REGISTER_R8, 526 R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY, 527 R9_CURSER_ROW_0, start, COMMAND_END)) 528 goto out; 529 if (i2c_getdata(t, end - start + 1, buf)) 530 goto out; 531 err = -EFAULT; 532 if (copy_to_user(req->buffer + start - req->start, buf, size)) 533 goto out; 534 } 535 err = 0; 536out: 537 kfree(buf); 538 return err; 539} 540 541/* Stops the acquisition circuit given in dau_no. The page buffer associated 542 * with this acquisition circuit will no more be updated. The other daus are 543 * not affected. 544 * 545 * Return value: 0 if successful 546 */ 547static inline int saa5246a_stop_dau(struct saa5246a_device *t, 548 unsigned char dau_no) 549{ 550 if (dau_no >= NUM_DAUS) 551 return -EINVAL; 552 if (i2c_senddata(t, SAA5246A_REGISTER_R2, 553 554 R2_IN_R3_SELECT_PAGE_HUNDREDS | 555 dau_no << 4 | 556 R2_BANK_0 | 557 R2_HAMMING_CHECK_OFF, 558 559 R3_PAGE_HUNDREDS_0 | 560 R3_HOLD_PAGE | 561 R3_PAGE_HUNDREDS_DO_NOT_CARE, 562 563 COMMAND_END)) 564 { 565 return -EIO; 566 } 567 t->is_searching[dau_no] = false; 568 return 0; 569} 570 571/* Handles ioctls defined in videotext.h 572 * 573 * Returns 0 if successful 574 */ 575static int do_saa5246a_ioctl(struct inode *inode, struct file *file, 576 unsigned int cmd, void *arg) 577{ 578 struct video_device *vd = video_devdata(file); 579 struct saa5246a_device *t=vd->priv; 580 switch(cmd) 581 { 582 case VTXIOCGETINFO: 583 { 584 vtx_info_t *info = arg; 585 586 info->version_major = MAJOR_VERSION; 587 info->version_minor = MINOR_VERSION; 588 info->numpages = NUM_DAUS; 589 return 0; 590 } 591 592 case VTXIOCCLRPAGE: 593 { 594 vtx_pagereq_t *req = arg; 595 596 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) 597 return -EINVAL; 598 memset(t->pgbuf[req->pgbuf], ' ', sizeof(t->pgbuf[0])); 599 return 0; 600 } 601 602 case VTXIOCCLRFOUND: 603 { 604 vtx_pagereq_t *req = arg; 605 606 if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS) 607 return -EINVAL; 608 return(saa5246a_clear_found_bit(t, req->pgbuf)); 609 } 610 611 case VTXIOCPAGEREQ: 612 { 613 vtx_pagereq_t *req = arg; 614 615 return(saa5246a_request_page(t, req)); 616 } 617 618 case VTXIOCGETSTAT: 619 { 620 vtx_pagereq_t *req = arg; 621 vtx_pageinfo_t info; 622 int rval; 623 624 if ((rval = saa5246a_get_status(t, &info, req->pgbuf))) 625 return rval; 626 if(copy_to_user(req->buffer, &info, 627 sizeof(vtx_pageinfo_t))) 628 return -EFAULT; 629 return 0; 630 } 631 632 case VTXIOCGETPAGE: 633 { 634 vtx_pagereq_t *req = arg; 635 636 return(saa5246a_get_page(t, req)); 637 } 638 639 case VTXIOCSTOPDAU: 640 { 641 vtx_pagereq_t *req = arg; 642 643 return(saa5246a_stop_dau(t, req->pgbuf)); 644 } 645 646 case VTXIOCPUTPAGE: 647 case VTXIOCSETDISP: 648 case VTXIOCPUTSTAT: 649 return 0; 650 651 case VTXIOCCLRCACHE: 652 { 653 return 0; 654 } 655 656 case VTXIOCSETVIRT: 657 { 658 /* I do not know what "virtual mode" means */ 659 return 0; 660 } 661 } 662 return -EINVAL; 663} 664 665/* 666 * Translates old vtx IOCTLs to new ones 667 * 668 * This keeps new kernel versions compatible with old userspace programs. 669 */ 670static inline unsigned int vtx_fix_command(unsigned int cmd) 671{ 672 switch (cmd) { 673 case VTXIOCGETINFO_OLD: 674 cmd = VTXIOCGETINFO; 675 break; 676 case VTXIOCCLRPAGE_OLD: 677 cmd = VTXIOCCLRPAGE; 678 break; 679 case VTXIOCCLRFOUND_OLD: 680 cmd = VTXIOCCLRFOUND; 681 break; 682 case VTXIOCPAGEREQ_OLD: 683 cmd = VTXIOCPAGEREQ; 684 break; 685 case VTXIOCGETSTAT_OLD: 686 cmd = VTXIOCGETSTAT; 687 break; 688 case VTXIOCGETPAGE_OLD: 689 cmd = VTXIOCGETPAGE; 690 break; 691 case VTXIOCSTOPDAU_OLD: 692 cmd = VTXIOCSTOPDAU; 693 break; 694 case VTXIOCPUTPAGE_OLD: 695 cmd = VTXIOCPUTPAGE; 696 break; 697 case VTXIOCSETDISP_OLD: 698 cmd = VTXIOCSETDISP; 699 break; 700 case VTXIOCPUTSTAT_OLD: 701 cmd = VTXIOCPUTSTAT; 702 break; 703 case VTXIOCCLRCACHE_OLD: 704 cmd = VTXIOCCLRCACHE; 705 break; 706 case VTXIOCSETVIRT_OLD: 707 cmd = VTXIOCSETVIRT; 708 break; 709 } 710 return cmd; 711} 712 713/* 714 * Handle the locking 715 */ 716static int saa5246a_ioctl(struct inode *inode, struct file *file, 717 unsigned int cmd, unsigned long arg) 718{ 719 struct video_device *vd = video_devdata(file); 720 struct saa5246a_device *t = vd->priv; 721 int err; 722 723 cmd = vtx_fix_command(cmd); 724 mutex_lock(&t->lock); 725 err = video_usercopy(inode, file, cmd, arg, do_saa5246a_ioctl); 726 mutex_unlock(&t->lock); 727 return err; 728} 729 730static int saa5246a_open(struct inode *inode, struct file *file) 731{ 732 struct video_device *vd = video_devdata(file); 733 struct saa5246a_device *t = vd->priv; 734 int err; 735 736 err = video_exclusive_open(inode,file); 737 if (err < 0) 738 return err; 739 740 if (t->client==NULL) { 741 err = -ENODEV; 742 goto fail; 743 } 744 745 if (i2c_senddata(t, SAA5246A_REGISTER_R0, 746 747 R0_SELECT_R11 | 748 R0_PLL_TIME_CONSTANT_LONG | 749 R0_ENABLE_nODD_EVEN_OUTPUT | 750 R0_ENABLE_HDR_POLL | 751 R0_DO_NOT_FORCE_nODD_EVEN_LOW_IF_PICTURE_DISPLAYED | 752 R0_NO_FREE_RUN_PLL | 753 R0_NO_AUTOMATIC_FASTEXT_PROMPT, 754 755 R1_NON_INTERLACED_312_312_LINES | 756 R1_DEW | 757 R1_EXTENDED_PACKET_DISABLE | 758 R1_DAUS_ALL_ON | 759 R1_8_BITS_NO_PARITY | 760 R1_VCS_TO_SCS, 761 762 COMMAND_END) || 763 i2c_senddata(t, SAA5246A_REGISTER_R4, 764 765 /* We do not care much for the TV display but nevertheless we 766 * need the currently displayed page later because only on that 767 * page the time is updated. */ 768 R4_DISPLAY_PAGE_4, 769 770 COMMAND_END)) 771 { 772 err = -EIO; 773 goto fail; 774 } 775 776 return 0; 777 778fail: 779 video_exclusive_release(inode,file); 780 return err; 781} 782 783static int saa5246a_release(struct inode *inode, struct file *file) 784{ 785 struct video_device *vd = video_devdata(file); 786 struct saa5246a_device *t = vd->priv; 787 788 /* Stop all acquisition circuits. */ 789 i2c_senddata(t, SAA5246A_REGISTER_R1, 790 791 R1_INTERLACED_312_AND_HALF_312_AND_HALF_LINES | 792 R1_DEW | 793 R1_EXTENDED_PACKET_DISABLE | 794 R1_DAUS_ALL_OFF | 795 R1_8_BITS_NO_PARITY | 796 R1_VCS_TO_SCS, 797 798 COMMAND_END); 799 video_exclusive_release(inode,file); 800 return 0; 801} 802 803static int __init init_saa_5246a (void) 804{ 805 printk(KERN_INFO 806 "SAA5246A (or compatible) Teletext decoder driver version %d.%d\n", 807 MAJOR_VERSION, MINOR_VERSION); 808 return i2c_add_driver(&i2c_driver_videotext); 809} 810 811static void __exit cleanup_saa_5246a (void) 812{ 813 i2c_del_driver(&i2c_driver_videotext); 814} 815 816module_init(init_saa_5246a); 817module_exit(cleanup_saa_5246a); 818 819static const struct file_operations saa_fops = { 820 .owner = THIS_MODULE, 821 .open = saa5246a_open, 822 .release = saa5246a_release, 823 .ioctl = saa5246a_ioctl, 824 .llseek = no_llseek, 825}; 826 827static struct video_device saa_template = 828{ 829 .owner = THIS_MODULE, 830 .name = IF_NAME, 831 .type = VID_TYPE_TELETEXT, 832 .fops = &saa_fops, 833 .release = video_device_release, 834 .minor = -1, 835}; 836