diff options
author | Oliver Endriss <o.endriss@gmx.de> | 2009-12-23 14:26:17 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-02-26 13:10:54 -0500 |
commit | 9fdd797659de7a989025c64c336542ac9c15d4d1 (patch) | |
tree | 65daa83e8e91dee27058defa6c5a195d8b5fc21c /drivers/media/dvb | |
parent | cf1b12f2b355a29c44dad426f545db8fa26bd81c (diff) |
V4L/DVB: ngene: Code cleanup
Remove/comment-out unused code, make some functions/declarations static.
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/ngene/ngene-core.c | 790 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-ioctls.h | 216 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-snd.c | 421 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene-v4l2.c | 1937 | ||||
-rw-r--r-- | drivers/media/dvb/ngene/ngene.h | 11 |
5 files changed, 10 insertions, 3365 deletions
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 907a5032784e..6f1b06618147 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -48,17 +48,10 @@ | |||
48 | #include "stv090x.h" | 48 | #include "stv090x.h" |
49 | #include "lnbh24.h" | 49 | #include "lnbh24.h" |
50 | 50 | ||
51 | #ifdef NGENE_COMMAND_API | ||
52 | #include "ngene-ioctls.h" | ||
53 | #endif | ||
54 | |||
55 | static int one_adapter = 1; | 51 | static int one_adapter = 1; |
56 | module_param(one_adapter, int, 0444); | 52 | module_param(one_adapter, int, 0444); |
57 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); | 53 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); |
58 | 54 | ||
59 | static int copy_eeprom; | ||
60 | module_param(copy_eeprom, int, 0444); | ||
61 | MODULE_PARM_DESC(copy_eeprom, "Copy eeprom."); | ||
62 | 55 | ||
63 | static int debug; | 56 | static int debug; |
64 | module_param(debug, int, 0444); | 57 | module_param(debug, int, 0444); |
@@ -342,19 +335,8 @@ static int ngene_command(struct ngene *dev, struct ngene_command *com) | |||
342 | return result; | 335 | return result; |
343 | } | 336 | } |
344 | 337 | ||
345 | int ngene_command_nop(struct ngene *dev) | ||
346 | { | ||
347 | struct ngene_command com; | ||
348 | |||
349 | com.cmd.hdr.Opcode = CMD_NOP; | ||
350 | com.cmd.hdr.Length = 0; | ||
351 | com.in_len = 0; | ||
352 | com.out_len = 0; | ||
353 | |||
354 | return ngene_command(dev, &com); | ||
355 | } | ||
356 | 338 | ||
357 | int ngene_command_i2c_read(struct ngene *dev, u8 adr, | 339 | static int ngene_command_i2c_read(struct ngene *dev, u8 adr, |
358 | u8 *out, u8 outlen, u8 *in, u8 inlen, int flag) | 340 | u8 *out, u8 outlen, u8 *in, u8 inlen, int flag) |
359 | { | 341 | { |
360 | struct ngene_command com; | 342 | struct ngene_command com; |
@@ -381,7 +363,8 @@ int ngene_command_i2c_read(struct ngene *dev, u8 adr, | |||
381 | return 0; | 363 | return 0; |
382 | } | 364 | } |
383 | 365 | ||
384 | int ngene_command_i2c_write(struct ngene *dev, u8 adr, u8 *out, u8 outlen) | 366 | static int ngene_command_i2c_write(struct ngene *dev, u8 adr, |
367 | u8 *out, u8 outlen) | ||
385 | { | 368 | { |
386 | struct ngene_command com; | 369 | struct ngene_command com; |
387 | 370 | ||
@@ -435,81 +418,6 @@ static int ngene_command_load_firmware(struct ngene *dev, | |||
435 | return ngene_command(dev, &com); | 418 | return ngene_command(dev, &com); |
436 | } | 419 | } |
437 | 420 | ||
438 | int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type) | ||
439 | { | ||
440 | struct ngene_command com; | ||
441 | |||
442 | com.cmd.hdr.Opcode = type ? CMD_SFR_READ : CMD_IRAM_READ; | ||
443 | com.cmd.hdr.Length = 1; | ||
444 | com.cmd.SfrIramRead.address = adr; | ||
445 | com.in_len = 1; | ||
446 | com.out_len = 2; | ||
447 | |||
448 | if (ngene_command(dev, &com) < 0) | ||
449 | return -EIO; | ||
450 | |||
451 | *data = com.cmd.raw8[1]; | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type) | ||
456 | { | ||
457 | struct ngene_command com; | ||
458 | |||
459 | com.cmd.hdr.Opcode = type ? CMD_SFR_WRITE : CMD_IRAM_WRITE; | ||
460 | com.cmd.hdr.Length = 2; | ||
461 | com.cmd.SfrIramWrite.address = adr; | ||
462 | com.cmd.SfrIramWrite.data = data; | ||
463 | com.in_len = 2; | ||
464 | com.out_len = 1; | ||
465 | |||
466 | if (ngene_command(dev, &com) < 0) | ||
467 | return -EIO; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int ngene_command_config_uart(struct ngene *dev, u8 config, | ||
473 | tx_cb_t *tx_cb, rx_cb_t *rx_cb) | ||
474 | { | ||
475 | struct ngene_command com; | ||
476 | |||
477 | com.cmd.hdr.Opcode = CMD_CONFIGURE_UART; | ||
478 | com.cmd.hdr.Length = sizeof(struct FW_CONFIGURE_UART) - 2; | ||
479 | com.cmd.ConfigureUart.UartControl = config; | ||
480 | com.in_len = sizeof(struct FW_CONFIGURE_UART); | ||
481 | com.out_len = 0; | ||
482 | |||
483 | if (ngene_command(dev, &com) < 0) | ||
484 | return -EIO; | ||
485 | |||
486 | dev->TxEventNotify = tx_cb; | ||
487 | dev->RxEventNotify = rx_cb; | ||
488 | |||
489 | dprintk(KERN_DEBUG DEVICE_NAME ": Set UART config %02x.\n", config); | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
494 | static void tx_cb(struct ngene *dev, u32 ts) | ||
495 | { | ||
496 | dev->tx_busy = 0; | ||
497 | wake_up_interruptible(&dev->tx_wq); | ||
498 | } | ||
499 | |||
500 | static void rx_cb(struct ngene *dev, u32 ts, u8 c) | ||
501 | { | ||
502 | int rp = dev->uart_rp; | ||
503 | int nwp, wp = dev->uart_wp; | ||
504 | |||
505 | /* dprintk(KERN_DEBUG DEVICE_NAME ": %c\n", c); */ | ||
506 | nwp = (wp + 1) % (UART_RBUF_LEN); | ||
507 | if (nwp == rp) | ||
508 | return; | ||
509 | dev->uart_rbuf[wp] = c; | ||
510 | dev->uart_wp = nwp; | ||
511 | wake_up_interruptible(&dev->rx_wq); | ||
512 | } | ||
513 | 421 | ||
514 | static int ngene_command_config_buf(struct ngene *dev, u8 config) | 422 | static int ngene_command_config_buf(struct ngene *dev, u8 config) |
515 | { | 423 | { |
@@ -555,16 +463,6 @@ static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) | |||
555 | return ngene_command(dev, &com); | 463 | return ngene_command(dev, &com); |
556 | } | 464 | } |
557 | 465 | ||
558 | /* The reset is only wired to GPIO4 on MicRacer Revision 1.10 ! | ||
559 | Also better set bootdelay to 1 in nvram or less. */ | ||
560 | static void ngene_reset_decypher(struct ngene *dev) | ||
561 | { | ||
562 | printk(KERN_INFO DEVICE_NAME ": Resetting Decypher.\n"); | ||
563 | ngene_command_gpio_set(dev, 4, 0); | ||
564 | msleep(1); | ||
565 | ngene_command_gpio_set(dev, 4, 1); | ||
566 | msleep(2000); | ||
567 | } | ||
568 | 466 | ||
569 | /* | 467 | /* |
570 | 02000640 is sample on rising edge. | 468 | 02000640 is sample on rising edge. |
@@ -693,8 +591,8 @@ static void clear_buffers(struct ngene_channel *chan) | |||
693 | } | 591 | } |
694 | } | 592 | } |
695 | 593 | ||
696 | int ngene_command_stream_control(struct ngene *dev, u8 stream, u8 control, | 594 | static int ngene_command_stream_control(struct ngene *dev, u8 stream, |
697 | u8 mode, u8 flags) | 595 | u8 control, u8 mode, u8 flags) |
698 | { | 596 | { |
699 | struct ngene_channel *chan = &dev->channel[stream]; | 597 | struct ngene_channel *chan = &dev->channel[stream]; |
700 | struct ngene_command com; | 598 | struct ngene_command com; |
@@ -847,23 +745,6 @@ int ngene_command_stream_control(struct ngene *dev, u8 stream, u8 control, | |||
847 | return 0; | 745 | return 0; |
848 | } | 746 | } |
849 | 747 | ||
850 | int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, | ||
851 | u16 lines, u16 bpl, u16 vblines, u16 vbibpl) | ||
852 | { | ||
853 | if (!(mode & SMODE_TRANSPORT_STREAM)) | ||
854 | return -EINVAL; | ||
855 | |||
856 | if (lines * bpl > MAX_VIDEO_BUFFER_SIZE) | ||
857 | return -EINVAL; | ||
858 | |||
859 | if ((mode & SMODE_TRANSPORT_STREAM) && (((bpl * lines) & 0xff) != 0)) | ||
860 | return -EINVAL; | ||
861 | |||
862 | if ((mode & SMODE_VIDEO_CAPTURE) && (bpl & 7) != 0) | ||
863 | return -EINVAL; | ||
864 | |||
865 | return ngene_command_stream_control(dev, stream, control, mode, 0); | ||
866 | } | ||
867 | 748 | ||
868 | /****************************************************************************/ | 749 | /****************************************************************************/ |
869 | /* I2C **********************************************************************/ | 750 | /* I2C **********************************************************************/ |
@@ -924,13 +805,12 @@ done: | |||
924 | } | 805 | } |
925 | 806 | ||
926 | 807 | ||
927 | |||
928 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) | 808 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) |
929 | { | 809 | { |
930 | return I2C_FUNC_SMBUS_EMUL; | 810 | return I2C_FUNC_SMBUS_EMUL; |
931 | } | 811 | } |
932 | 812 | ||
933 | struct i2c_algorithm ngene_i2c_algo = { | 813 | static struct i2c_algorithm ngene_i2c_algo = { |
934 | .master_xfer = ngene_i2c_master_xfer, | 814 | .master_xfer = ngene_i2c_master_xfer, |
935 | .functionality = ngene_i2c_functionality, | 815 | .functionality = ngene_i2c_functionality, |
936 | }; | 816 | }; |
@@ -956,476 +836,6 @@ static int ngene_i2c_init(struct ngene *dev, int dev_nr) | |||
956 | return i2c_add_adapter(adap); | 836 | return i2c_add_adapter(adap); |
957 | } | 837 | } |
958 | 838 | ||
959 | int i2c_write(struct i2c_adapter *adapter, u8 adr, u8 data) | ||
960 | { | ||
961 | u8 m[1] = {data}; | ||
962 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 1}; | ||
963 | |||
964 | if (i2c_transfer(adapter, &msg, 1) != 1) { | ||
965 | printk(KERN_ERR DEVICE_NAME | ||
966 | ": Failed to write to I2C adr %02x!\n", adr); | ||
967 | return -1; | ||
968 | } | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | |||
973 | static int i2c_write_read(struct i2c_adapter *adapter, | ||
974 | u8 adr, u8 *w, u8 wlen, u8 *r, u8 rlen) | ||
975 | { | ||
976 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
977 | .buf = w, .len = wlen}, | ||
978 | {.addr = adr, .flags = I2C_M_RD, | ||
979 | .buf = r, .len = rlen} }; | ||
980 | |||
981 | if (i2c_transfer(adapter, msgs, 2) != 2) { | ||
982 | printk(KERN_ERR DEVICE_NAME ": error in i2c_write_read\n"); | ||
983 | return -1; | ||
984 | } | ||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | static int test_dec_i2c(struct i2c_adapter *adapter, int reg) | ||
989 | { | ||
990 | u8 data[256] = { reg, 0x00, 0x93, 0x78, 0x43, 0x45 }; | ||
991 | u8 data2[256]; | ||
992 | int i; | ||
993 | |||
994 | memset(data2, 0, 256); | ||
995 | i2c_write_read(adapter, 0x66, data, 2, data2, 4); | ||
996 | for (i = 0; i < 4; i++) | ||
997 | printk("%02x ", data2[i]); | ||
998 | printk("\n"); | ||
999 | |||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | |||
1004 | /****************************************************************************/ | ||
1005 | /* EEPROM TAGS **************************************************************/ | ||
1006 | /****************************************************************************/ | ||
1007 | |||
1008 | #define MICNG_EE_START 0x0100 | ||
1009 | #define MICNG_EE_END 0x0FF0 | ||
1010 | |||
1011 | #define MICNG_EETAG_END0 0x0000 | ||
1012 | #define MICNG_EETAG_END1 0xFFFF | ||
1013 | |||
1014 | /* 0x0001 - 0x000F reserved for housekeeping */ | ||
1015 | /* 0xFFFF - 0xFFFE reserved for housekeeping */ | ||
1016 | |||
1017 | /* Micronas assigned tags | ||
1018 | EEProm tags for hardware support */ | ||
1019 | |||
1020 | #define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */ | ||
1021 | #define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */ | ||
1022 | |||
1023 | #define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */ | ||
1024 | #define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */ | ||
1025 | |||
1026 | /* Tag range for OEMs */ | ||
1027 | |||
1028 | #define MICNG_EETAG_OEM_FIRST 0xC000 | ||
1029 | #define MICNG_EETAG_OEM_LAST 0xFFEF | ||
1030 | |||
1031 | static int i2c_write_eeprom(struct i2c_adapter *adapter, | ||
1032 | u8 adr, u16 reg, u8 data) | ||
1033 | { | ||
1034 | u8 m[3] = {(reg >> 8), (reg & 0xff), data}; | ||
1035 | struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, | ||
1036 | .len = sizeof(m)}; | ||
1037 | |||
1038 | if (i2c_transfer(adapter, &msg, 1) != 1) { | ||
1039 | dprintk(KERN_ERR DEVICE_NAME ": Error writing EEPROM!\n"); | ||
1040 | return -EIO; | ||
1041 | } | ||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int i2c_read_eeprom(struct i2c_adapter *adapter, | ||
1046 | u8 adr, u16 reg, u8 *data, int len) | ||
1047 | { | ||
1048 | u8 msg[2] = {(reg >> 8), (reg & 0xff)}; | ||
1049 | struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||
1050 | .buf = msg, .len = 2 }, | ||
1051 | {.addr = adr, .flags = I2C_M_RD, | ||
1052 | .buf = data, .len = len} }; | ||
1053 | |||
1054 | if (i2c_transfer(adapter, msgs, 2) != 2) { | ||
1055 | dprintk(KERN_ERR DEVICE_NAME ": Error reading EEPROM\n"); | ||
1056 | return -EIO; | ||
1057 | } | ||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | |||
1062 | static int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr) | ||
1063 | { | ||
1064 | u8 buf[64]; | ||
1065 | int i; | ||
1066 | |||
1067 | if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { | ||
1068 | printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); | ||
1069 | return -1; | ||
1070 | } | ||
1071 | for (i = 0; i < sizeof(buf); i++) { | ||
1072 | if (!(i & 15)) | ||
1073 | printk("\n"); | ||
1074 | printk("%02x ", buf[i]); | ||
1075 | } | ||
1076 | printk("\n"); | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static int i2c_copy_eeprom(struct i2c_adapter *adapter, u8 adr, u8 adr2) | ||
1082 | { | ||
1083 | u8 buf[64]; | ||
1084 | int i; | ||
1085 | |||
1086 | if (i2c_read_eeprom(adapter, adr, 0x0000, buf, sizeof(buf))) { | ||
1087 | printk(KERN_ERR DEVICE_NAME ": No EEPROM?\n"); | ||
1088 | return -1; | ||
1089 | } | ||
1090 | buf[36] = 0xc3; | ||
1091 | buf[39] = 0xab; | ||
1092 | for (i = 0; i < sizeof(buf); i++) { | ||
1093 | i2c_write_eeprom(adapter, adr2, i, buf[i]); | ||
1094 | msleep(10); | ||
1095 | } | ||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | /****************************************************************************/ | ||
1101 | /* COMMAND API interface ****************************************************/ | ||
1102 | /****************************************************************************/ | ||
1103 | |||
1104 | #ifdef NGENE_COMMAND_API | ||
1105 | |||
1106 | static int command_do_ioctl(struct inode *inode, struct file *file, | ||
1107 | unsigned int cmd, void *parg) | ||
1108 | { | ||
1109 | struct dvb_device *dvbdev = file->private_data; | ||
1110 | struct ngene_channel *chan = dvbdev->priv; | ||
1111 | struct ngene *dev = chan->dev; | ||
1112 | int err = 0; | ||
1113 | |||
1114 | switch (cmd) { | ||
1115 | case IOCTL_MIC_NO_OP: | ||
1116 | err = ngene_command_nop(dev); | ||
1117 | break; | ||
1118 | |||
1119 | case IOCTL_MIC_DOWNLOAD_FIRMWARE: | ||
1120 | break; | ||
1121 | |||
1122 | case IOCTL_MIC_I2C_READ: | ||
1123 | { | ||
1124 | MIC_I2C_READ *msg = parg; | ||
1125 | |||
1126 | err = ngene_command_i2c_read(dev, msg->I2CAddress >> 1, | ||
1127 | msg->OutData, msg->OutLength, | ||
1128 | msg->OutData, msg->InLength, 1); | ||
1129 | break; | ||
1130 | } | ||
1131 | |||
1132 | case IOCTL_MIC_I2C_WRITE: | ||
1133 | { | ||
1134 | MIC_I2C_WRITE *msg = parg; | ||
1135 | |||
1136 | err = ngene_command_i2c_write(dev, msg->I2CAddress >> 1, | ||
1137 | msg->Data, msg->Length); | ||
1138 | break; | ||
1139 | } | ||
1140 | |||
1141 | case IOCTL_MIC_TEST_GETMEM: | ||
1142 | { | ||
1143 | MIC_MEM *m = parg; | ||
1144 | |||
1145 | if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) | ||
1146 | return -EINVAL; | ||
1147 | |||
1148 | /* WARNING, only use this on x86, | ||
1149 | other archs may not swallow this */ | ||
1150 | err = copy_to_user(m->Data, dev->iomem + m->Start, m->Length); | ||
1151 | break; | ||
1152 | } | ||
1153 | |||
1154 | case IOCTL_MIC_TEST_SETMEM: | ||
1155 | { | ||
1156 | MIC_MEM *m = parg; | ||
1157 | |||
1158 | if (m->Length > 64 * 1024 || m->Start + m->Length > 64 * 1024) | ||
1159 | return -EINVAL; | ||
1160 | |||
1161 | err = copy_from_user(dev->iomem + m->Start, m->Data, m->Length); | ||
1162 | break; | ||
1163 | } | ||
1164 | |||
1165 | case IOCTL_MIC_SFR_READ: | ||
1166 | { | ||
1167 | MIC_IMEM *m = parg; | ||
1168 | |||
1169 | err = ngene_command_imem_read(dev, m->Address, &m->Data, 1); | ||
1170 | break; | ||
1171 | } | ||
1172 | |||
1173 | case IOCTL_MIC_SFR_WRITE: | ||
1174 | { | ||
1175 | MIC_IMEM *m = parg; | ||
1176 | |||
1177 | err = ngene_command_imem_write(dev, m->Address, m->Data, 1); | ||
1178 | break; | ||
1179 | } | ||
1180 | |||
1181 | case IOCTL_MIC_IRAM_READ: | ||
1182 | { | ||
1183 | MIC_IMEM *m = parg; | ||
1184 | |||
1185 | err = ngene_command_imem_read(dev, m->Address, &m->Data, 0); | ||
1186 | break; | ||
1187 | } | ||
1188 | |||
1189 | case IOCTL_MIC_IRAM_WRITE: | ||
1190 | { | ||
1191 | MIC_IMEM *m = parg; | ||
1192 | |||
1193 | err = ngene_command_imem_write(dev, m->Address, m->Data, 0); | ||
1194 | break; | ||
1195 | } | ||
1196 | |||
1197 | case IOCTL_MIC_STREAM_CONTROL: | ||
1198 | { | ||
1199 | MIC_STREAM_CONTROL *m = parg; | ||
1200 | |||
1201 | err = ngene_stream_control(dev, m->Stream, m->Control, m->Mode, | ||
1202 | m->nLines, m->nBytesPerLine, | ||
1203 | m->nVBILines, m->nBytesPerVBILine); | ||
1204 | break; | ||
1205 | } | ||
1206 | |||
1207 | default: | ||
1208 | err = -EINVAL; | ||
1209 | break; | ||
1210 | } | ||
1211 | return err; | ||
1212 | } | ||
1213 | |||
1214 | static int command_ioctl(struct inode *inode, struct file *file, | ||
1215 | unsigned int cmd, unsigned long arg) | ||
1216 | { | ||
1217 | void *parg = (void *)arg, *pbuf = NULL; | ||
1218 | char buf[64]; | ||
1219 | int res = -EFAULT; | ||
1220 | |||
1221 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | ||
1222 | parg = buf; | ||
1223 | if (_IOC_SIZE(cmd) > sizeof(buf)) { | ||
1224 | pbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | ||
1225 | if (!pbuf) | ||
1226 | return -ENOMEM; | ||
1227 | parg = pbuf; | ||
1228 | } | ||
1229 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | ||
1230 | goto error; | ||
1231 | } | ||
1232 | res = command_do_ioctl(inode, file, cmd, parg); | ||
1233 | if (res < 0) | ||
1234 | goto error; | ||
1235 | if (_IOC_DIR(cmd) & _IOC_READ) | ||
1236 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | ||
1237 | res = -EFAULT; | ||
1238 | error: | ||
1239 | kfree(pbuf); | ||
1240 | return res; | ||
1241 | } | ||
1242 | |||
1243 | struct page *ngene_nopage(struct vm_area_struct *vma, | ||
1244 | unsigned long address, int *type) | ||
1245 | { | ||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static int ngene_mmap(struct file *file, struct vm_area_struct *vma) | ||
1250 | { | ||
1251 | struct dvb_device *dvbdev = file->private_data; | ||
1252 | struct ngene_channel *chan = dvbdev->priv; | ||
1253 | struct ngene *dev = chan->dev; | ||
1254 | |||
1255 | unsigned long size = vma->vm_end - vma->vm_start; | ||
1256 | unsigned long off = vma->vm_pgoff << PAGE_SHIFT; | ||
1257 | unsigned long padr = pci_resource_start(dev->pci_dev, 0) + off; | ||
1258 | unsigned long psize = pci_resource_len(dev->pci_dev, 0) - off; | ||
1259 | |||
1260 | if (size > psize) | ||
1261 | return -EINVAL; | ||
1262 | |||
1263 | if (io_remap_pfn_range(vma, vma->vm_start, padr >> PAGE_SHIFT, size, | ||
1264 | vma->vm_page_prot)) | ||
1265 | return -EAGAIN; | ||
1266 | return 0; | ||
1267 | } | ||
1268 | |||
1269 | static int write_uart(struct ngene *dev, u8 *data, int len) | ||
1270 | { | ||
1271 | struct ngene_command com; | ||
1272 | |||
1273 | com.cmd.hdr.Opcode = CMD_WRITE_UART; | ||
1274 | com.cmd.hdr.Length = len; | ||
1275 | memcpy(com.cmd.WriteUart.Data, data, len); | ||
1276 | com.cmd.WriteUart.Data[len] = 0; | ||
1277 | com.cmd.WriteUart.Data[len + 1] = 0; | ||
1278 | com.in_len = len; | ||
1279 | com.out_len = 0; | ||
1280 | |||
1281 | if (ngene_command(dev, &com) < 0) | ||
1282 | return -EIO; | ||
1283 | |||
1284 | return 0; | ||
1285 | } | ||
1286 | |||
1287 | static int send_cli(struct ngene *dev, char *cmd) | ||
1288 | { | ||
1289 | /* printk(KERN_INFO DEVICE_NAME ": %s", cmd); */ | ||
1290 | return write_uart(dev, cmd, strlen(cmd)); | ||
1291 | } | ||
1292 | |||
1293 | static int send_cli_val(struct ngene *dev, char *cmd, u32 val) | ||
1294 | { | ||
1295 | char s[32]; | ||
1296 | |||
1297 | snprintf(s, 32, "%s %d\n", cmd, val); | ||
1298 | /* printk(KERN_INFO DEVICE_NAME ": %s", s); */ | ||
1299 | return write_uart(dev, s, strlen(s)); | ||
1300 | } | ||
1301 | |||
1302 | static int ngene_command_write_uart_user(struct ngene *dev, | ||
1303 | const u8 *data, int len) | ||
1304 | { | ||
1305 | struct ngene_command com; | ||
1306 | |||
1307 | dev->tx_busy = 1; | ||
1308 | com.cmd.hdr.Opcode = CMD_WRITE_UART; | ||
1309 | com.cmd.hdr.Length = len; | ||
1310 | |||
1311 | if (copy_from_user(com.cmd.WriteUart.Data, data, len)) | ||
1312 | return -EFAULT; | ||
1313 | com.in_len = len; | ||
1314 | com.out_len = 0; | ||
1315 | |||
1316 | if (ngene_command(dev, &com) < 0) | ||
1317 | return -EIO; | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | static ssize_t uart_write(struct file *file, const char *buf, | ||
1323 | size_t count, loff_t *ppos) | ||
1324 | { | ||
1325 | struct dvb_device *dvbdev = file->private_data; | ||
1326 | struct ngene_channel *chan = dvbdev->priv; | ||
1327 | struct ngene *dev = chan->dev; | ||
1328 | int len, ret = 0; | ||
1329 | size_t left = count; | ||
1330 | |||
1331 | while (left) { | ||
1332 | len = left; | ||
1333 | if (len > 250) | ||
1334 | len = 250; | ||
1335 | ret = wait_event_interruptible(dev->tx_wq, dev->tx_busy == 0); | ||
1336 | if (ret < 0) | ||
1337 | return ret; | ||
1338 | ngene_command_write_uart_user(dev, buf, len); | ||
1339 | left -= len; | ||
1340 | buf += len; | ||
1341 | } | ||
1342 | return count; | ||
1343 | } | ||
1344 | |||
1345 | static ssize_t ts_write(struct file *file, const char *buf, | ||
1346 | size_t count, loff_t *ppos) | ||
1347 | { | ||
1348 | struct dvb_device *dvbdev = file->private_data; | ||
1349 | struct ngene_channel *chan = dvbdev->priv; | ||
1350 | struct ngene *dev = chan->dev; | ||
1351 | |||
1352 | if (wait_event_interruptible(dev->tsout_rbuf.queue, | ||
1353 | dvb_ringbuffer_free | ||
1354 | (&dev->tsout_rbuf) >= count) < 0) | ||
1355 | return 0; | ||
1356 | |||
1357 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count); | ||
1358 | |||
1359 | return count; | ||
1360 | } | ||
1361 | |||
1362 | static ssize_t uart_read(struct file *file, char *buf, | ||
1363 | size_t count, loff_t *ppos) | ||
1364 | { | ||
1365 | struct dvb_device *dvbdev = file->private_data; | ||
1366 | struct ngene_channel *chan = dvbdev->priv; | ||
1367 | struct ngene *dev = chan->dev; | ||
1368 | int left; | ||
1369 | int wp, rp, avail, len; | ||
1370 | |||
1371 | if (!dev->uart_rbuf) | ||
1372 | return -EINVAL; | ||
1373 | if (count > 128) | ||
1374 | count = 128; | ||
1375 | left = count; | ||
1376 | while (left) { | ||
1377 | if (wait_event_interruptible(dev->rx_wq, | ||
1378 | dev->uart_wp != dev->uart_rp) < 0) | ||
1379 | return -EAGAIN; | ||
1380 | wp = dev->uart_wp; | ||
1381 | rp = dev->uart_rp; | ||
1382 | avail = (wp - rp); | ||
1383 | |||
1384 | if (avail < 0) | ||
1385 | avail += UART_RBUF_LEN; | ||
1386 | if (avail > left) | ||
1387 | avail = left; | ||
1388 | if (wp < rp) { | ||
1389 | len = UART_RBUF_LEN - rp; | ||
1390 | if (len > avail) | ||
1391 | len = avail; | ||
1392 | if (copy_to_user(buf, dev->uart_rbuf + rp, len)) | ||
1393 | return -EFAULT; | ||
1394 | if (len < avail) | ||
1395 | if (copy_to_user(buf + len, dev->uart_rbuf, | ||
1396 | avail - len)) | ||
1397 | return -EFAULT; | ||
1398 | } else { | ||
1399 | if (copy_to_user(buf, dev->uart_rbuf + rp, avail)) | ||
1400 | return -EFAULT; | ||
1401 | } | ||
1402 | dev->uart_rp = (rp + avail) % UART_RBUF_LEN; | ||
1403 | left -= avail; | ||
1404 | buf += avail; | ||
1405 | } | ||
1406 | return count; | ||
1407 | } | ||
1408 | |||
1409 | static const struct file_operations command_fops = { | ||
1410 | .owner = THIS_MODULE, | ||
1411 | .read = uart_read, | ||
1412 | .write = ts_write, | ||
1413 | .ioctl = command_ioctl, | ||
1414 | .open = dvb_generic_open, | ||
1415 | .release = dvb_generic_release, | ||
1416 | .poll = 0, | ||
1417 | .mmap = ngene_mmap, | ||
1418 | }; | ||
1419 | |||
1420 | static struct dvb_device dvbdev_command = { | ||
1421 | .priv = 0, | ||
1422 | .readers = -1, | ||
1423 | .writers = -1, | ||
1424 | .users = -1, | ||
1425 | .fops = &command_fops, | ||
1426 | }; | ||
1427 | |||
1428 | #endif | ||
1429 | 839 | ||
1430 | /****************************************************************************/ | 840 | /****************************************************************************/ |
1431 | /* DVB functions and API interface ******************************************/ | 841 | /* DVB functions and API interface ******************************************/ |
@@ -1550,32 +960,6 @@ static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
1550 | { | 960 | { |
1551 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 961 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
1552 | struct ngene_channel *chan = dvbdmx->priv; | 962 | struct ngene_channel *chan = dvbdmx->priv; |
1553 | #ifdef NGENE_COMMAND_API | ||
1554 | struct ngene *dev = chan->dev; | ||
1555 | |||
1556 | if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { | ||
1557 | switch (dvbdmxfeed->pes_type) { | ||
1558 | case DMX_TS_PES_VIDEO: | ||
1559 | send_cli_val(dev, "vpid", dvbdmxfeed->pid); | ||
1560 | send_cli(dev, "res 1080i50\n"); | ||
1561 | /* send_cli(dev, "vdec mpeg2\n"); */ | ||
1562 | break; | ||
1563 | |||
1564 | case DMX_TS_PES_AUDIO: | ||
1565 | send_cli_val(dev, "apid", dvbdmxfeed->pid); | ||
1566 | send_cli(dev, "start\n"); | ||
1567 | break; | ||
1568 | |||
1569 | case DMX_TS_PES_PCR: | ||
1570 | send_cli_val(dev, "pcrpid", dvbdmxfeed->pid); | ||
1571 | break; | ||
1572 | |||
1573 | default: | ||
1574 | break; | ||
1575 | } | ||
1576 | |||
1577 | } | ||
1578 | #endif | ||
1579 | 963 | ||
1580 | if (chan->users == 0) { | 964 | if (chan->users == 0) { |
1581 | set_transfer(chan, 1); | 965 | set_transfer(chan, 1); |
@@ -1589,27 +973,6 @@ static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
1589 | { | 973 | { |
1590 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | 974 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; |
1591 | struct ngene_channel *chan = dvbdmx->priv; | 975 | struct ngene_channel *chan = dvbdmx->priv; |
1592 | #ifdef NGENE_COMMAND_API | ||
1593 | struct ngene *dev = chan->dev; | ||
1594 | |||
1595 | if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) { | ||
1596 | switch (dvbdmxfeed->pes_type) { | ||
1597 | case DMX_TS_PES_VIDEO: | ||
1598 | send_cli(dev, "stop\n"); | ||
1599 | break; | ||
1600 | |||
1601 | case DMX_TS_PES_AUDIO: | ||
1602 | break; | ||
1603 | |||
1604 | case DMX_TS_PES_PCR: | ||
1605 | break; | ||
1606 | |||
1607 | default: | ||
1608 | break; | ||
1609 | } | ||
1610 | |||
1611 | } | ||
1612 | #endif | ||
1613 | 976 | ||
1614 | if (--chan->users) | 977 | if (--chan->users) |
1615 | return chan->users; | 978 | return chan->users; |
@@ -1621,23 +984,6 @@ static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
1621 | 984 | ||
1622 | 985 | ||
1623 | 986 | ||
1624 | static int write_to_decoder(struct dvb_demux_feed *feed, | ||
1625 | const u8 *buf, size_t len) | ||
1626 | { | ||
1627 | struct dvb_demux *dvbdmx = feed->demux; | ||
1628 | struct ngene_channel *chan = dvbdmx->priv; | ||
1629 | struct ngene *dev = chan->dev; | ||
1630 | |||
1631 | if (wait_event_interruptible(dev->tsout_rbuf.queue, | ||
1632 | dvb_ringbuffer_free | ||
1633 | (&dev->tsout_rbuf) >= len) < 0) | ||
1634 | return 0; | ||
1635 | |||
1636 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, len); | ||
1637 | |||
1638 | return len; | ||
1639 | } | ||
1640 | |||
1641 | static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, | 987 | static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, |
1642 | int (*start_feed)(struct dvb_demux_feed *), | 988 | int (*start_feed)(struct dvb_demux_feed *), |
1643 | int (*stop_feed)(struct dvb_demux_feed *), | 989 | int (*stop_feed)(struct dvb_demux_feed *), |
@@ -1678,86 +1024,12 @@ static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, | |||
1678 | return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); | 1024 | return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); |
1679 | } | 1025 | } |
1680 | 1026 | ||
1681 | /****************************************************************************/ | ||
1682 | /* Decypher firmware loading ************************************************/ | ||
1683 | /****************************************************************************/ | ||
1684 | |||
1685 | #define DECYPHER_FW "decypher.fw" | ||
1686 | |||
1687 | static int dec_ts_send(struct ngene *dev, u8 *buf, u32 len) | ||
1688 | { | ||
1689 | while (dvb_ringbuffer_free(&dev->tsout_rbuf) < len) | ||
1690 | msleep(1); | ||
1691 | |||
1692 | |||
1693 | dvb_ringbuffer_write(&dev->tsout_rbuf, buf, len); | ||
1694 | |||
1695 | return len; | ||
1696 | } | ||
1697 | |||
1698 | u8 dec_fw_fill_ts[188] = { 0x47, 0x09, 0x0e, 0x10, 0xff, 0xff, 0x00, 0x00 }; | ||
1699 | |||
1700 | int dec_fw_send(struct ngene *dev, u8 *fw, u32 size) | ||
1701 | { | ||
1702 | struct ngene_channel *chan = &dev->channel[4]; | ||
1703 | u32 len = 180, cc = 0; | ||
1704 | u8 buf[8] = { 0x47, 0x09, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00 }; | ||
1705 | |||
1706 | set_transfer(chan, 1); | ||
1707 | msleep(100); | ||
1708 | while (size) { | ||
1709 | len = 180; | ||
1710 | if (len > size) | ||
1711 | len = size; | ||
1712 | buf[3] = 0x10 | (cc & 0x0f); | ||
1713 | buf[4] = (cc >> 8); | ||
1714 | buf[5] = cc & 0xff; | ||
1715 | buf[6] = len; | ||
1716 | |||
1717 | dec_ts_send(dev, buf, 8); | ||
1718 | dec_ts_send(dev, fw, len); | ||
1719 | if (len < 180) | ||
1720 | dec_ts_send(dev, dec_fw_fill_ts + len + 8, 180 - len); | ||
1721 | cc++; | ||
1722 | size -= len; | ||
1723 | fw += len; | ||
1724 | } | ||
1725 | for (len = 0; len < 512; len++) | ||
1726 | dec_ts_send(dev, dec_fw_fill_ts, 188); | ||
1727 | while (dvb_ringbuffer_avail(&dev->tsout_rbuf)) | ||
1728 | msleep(10); | ||
1729 | msleep(100); | ||
1730 | set_transfer(chan, 0); | ||
1731 | return 0; | ||
1732 | } | ||
1733 | |||
1734 | int dec_fw_boot(struct ngene *dev) | ||
1735 | { | ||
1736 | u32 size; | ||
1737 | const struct firmware *fw = NULL; | ||
1738 | u8 *dec_fw; | ||
1739 | |||
1740 | if (request_firmware(&fw, DECYPHER_FW, &dev->pci_dev->dev) < 0) { | ||
1741 | printk(KERN_ERR DEVICE_NAME | ||
1742 | ": %s not found. Check hotplug directory.\n", | ||
1743 | DECYPHER_FW); | ||
1744 | return -1; | ||
1745 | } | ||
1746 | printk(KERN_INFO DEVICE_NAME ": Booting decypher firmware file %s\n", | ||
1747 | DECYPHER_FW); | ||
1748 | |||
1749 | size = fw->size; | ||
1750 | dec_fw = (u8 *)fw->data; | ||
1751 | dec_fw_send(dev, dec_fw, size); | ||
1752 | release_firmware(fw); | ||
1753 | return 0; | ||
1754 | } | ||
1755 | 1027 | ||
1756 | /****************************************************************************/ | 1028 | /****************************************************************************/ |
1757 | /* nGene hardware init and release functions ********************************/ | 1029 | /* nGene hardware init and release functions ********************************/ |
1758 | /****************************************************************************/ | 1030 | /****************************************************************************/ |
1759 | 1031 | ||
1760 | void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb) | 1032 | static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb) |
1761 | { | 1033 | { |
1762 | struct SBufferHeader *Cur = rb->Head; | 1034 | struct SBufferHeader *Cur = rb->Head; |
1763 | u32 j; | 1035 | u32 j; |
@@ -1786,7 +1058,7 @@ void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb) | |||
1786 | pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead); | 1058 | pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead); |
1787 | } | 1059 | } |
1788 | 1060 | ||
1789 | void free_idlebuffer(struct ngene *dev, | 1061 | static void free_idlebuffer(struct ngene *dev, |
1790 | struct SRingBufferDescriptor *rb, | 1062 | struct SRingBufferDescriptor *rb, |
1791 | struct SRingBufferDescriptor *tb) | 1063 | struct SRingBufferDescriptor *tb) |
1792 | { | 1064 | { |
@@ -1804,7 +1076,7 @@ void free_idlebuffer(struct ngene *dev, | |||
1804 | } | 1076 | } |
1805 | } | 1077 | } |
1806 | 1078 | ||
1807 | void free_common_buffers(struct ngene *dev) | 1079 | static void free_common_buffers(struct ngene *dev) |
1808 | { | 1080 | { |
1809 | u32 i; | 1081 | u32 i; |
1810 | struct ngene_channel *chan; | 1082 | struct ngene_channel *chan; |
@@ -1832,7 +1104,7 @@ void free_common_buffers(struct ngene *dev) | |||
1832 | /* Ring buffer handling *****************************************************/ | 1104 | /* Ring buffer handling *****************************************************/ |
1833 | /****************************************************************************/ | 1105 | /****************************************************************************/ |
1834 | 1106 | ||
1835 | int create_ring_buffer(struct pci_dev *pci_dev, | 1107 | static int create_ring_buffer(struct pci_dev *pci_dev, |
1836 | struct SRingBufferDescriptor *descr, u32 NumBuffers) | 1108 | struct SRingBufferDescriptor *descr, u32 NumBuffers) |
1837 | { | 1109 | { |
1838 | dma_addr_t tmp; | 1110 | dma_addr_t tmp; |
@@ -2311,8 +1583,6 @@ static int ngene_start(struct ngene *dev) | |||
2311 | goto fail; | 1583 | goto fail; |
2312 | 1584 | ||
2313 | if (dev->card_info->fw_version == 17) { | 1585 | if (dev->card_info->fw_version == 17) { |
2314 | u8 hdtv_config[6] = | ||
2315 | {6144 / 64, 0, 0, 2048 / 64, 2048 / 64, 2048 / 64}; | ||
2316 | u8 tsin4_config[6] = | 1586 | u8 tsin4_config[6] = |
2317 | {3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0}; | 1587 | {3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0}; |
2318 | u8 default_config[6] = | 1588 | u8 default_config[6] = |
@@ -2321,30 +1591,14 @@ static int ngene_start(struct ngene *dev) | |||
2321 | 1591 | ||
2322 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | 1592 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) |
2323 | bconf = tsin4_config; | 1593 | bconf = tsin4_config; |
2324 | if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { | ||
2325 | bconf = hdtv_config; | ||
2326 | ngene_reset_decypher(dev); | ||
2327 | } | ||
2328 | dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n"); | 1594 | dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n"); |
2329 | stat = ngene_command_config_free_buf(dev, bconf); | 1595 | stat = ngene_command_config_free_buf(dev, bconf); |
2330 | } else { | 1596 | } else { |
2331 | int bconf = BUFFER_CONFIG_4422; | 1597 | int bconf = BUFFER_CONFIG_4422; |
2332 | |||
2333 | if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { | ||
2334 | bconf = BUFFER_CONFIG_8022; | ||
2335 | ngene_reset_decypher(dev); | ||
2336 | } | ||
2337 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | 1598 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) |
2338 | bconf = BUFFER_CONFIG_3333; | 1599 | bconf = BUFFER_CONFIG_3333; |
2339 | stat = ngene_command_config_buf(dev, bconf); | 1600 | stat = ngene_command_config_buf(dev, bconf); |
2340 | } | 1601 | } |
2341 | |||
2342 | if (dev->card_info->io_type[0] == NGENE_IO_HDTV) { | ||
2343 | ngene_command_config_uart(dev, 0xc1, tx_cb, rx_cb); | ||
2344 | test_dec_i2c(&dev->channel[0].i2c_adapter, 0); | ||
2345 | test_dec_i2c(&dev->channel[0].i2c_adapter, 1); | ||
2346 | } | ||
2347 | |||
2348 | return stat; | 1602 | return stat; |
2349 | fail: | 1603 | fail: |
2350 | ngwritel(0, NGENE_INT_ENABLE); | 1604 | ngwritel(0, NGENE_INT_ENABLE); |
@@ -2432,10 +1686,6 @@ static void release_channel(struct ngene_channel *chan) | |||
2432 | tasklet_kill(&chan->demux_tasklet); | 1686 | tasklet_kill(&chan->demux_tasklet); |
2433 | 1687 | ||
2434 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1688 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
2435 | #ifdef NGENE_COMMAND_API | ||
2436 | if (chan->command_dev) | ||
2437 | dvb_unregister_device(chan->command_dev); | ||
2438 | #endif | ||
2439 | if (chan->fe) { | 1689 | if (chan->fe) { |
2440 | dvb_unregister_frontend(chan->fe); | 1690 | dvb_unregister_frontend(chan->fe); |
2441 | dvb_frontend_detach(chan->fe); | 1691 | dvb_frontend_detach(chan->fe); |
@@ -2452,7 +1702,6 @@ static void release_channel(struct ngene_channel *chan) | |||
2452 | if (chan->number == 0 || !one_adapter) | 1702 | if (chan->number == 0 || !one_adapter) |
2453 | dvb_unregister_adapter(&dev->adapter[chan->number]); | 1703 | dvb_unregister_adapter(&dev->adapter[chan->number]); |
2454 | } | 1704 | } |
2455 | |||
2456 | } | 1705 | } |
2457 | 1706 | ||
2458 | static int init_channel(struct ngene_channel *chan) | 1707 | static int init_channel(struct ngene_channel *chan) |
@@ -2472,10 +1721,6 @@ static int init_channel(struct ngene_channel *chan) | |||
2472 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | 1721 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { |
2473 | if (nr >= STREAM_AUDIOIN1) | 1722 | if (nr >= STREAM_AUDIOIN1) |
2474 | chan->DataFormatFlags = DF_SWAP32; | 1723 | chan->DataFormatFlags = DF_SWAP32; |
2475 | |||
2476 | if (io & NGENE_IO_TSOUT) | ||
2477 | dec_fw_boot(dev); | ||
2478 | |||
2479 | if (nr == 0 || !one_adapter) { | 1724 | if (nr == 0 || !one_adapter) { |
2480 | adapter = &dev->adapter[nr]; | 1725 | adapter = &dev->adapter[nr]; |
2481 | ret = dvb_register_adapter(adapter, "nGene", | 1726 | ret = dvb_register_adapter(adapter, "nGene", |
@@ -2494,14 +1739,6 @@ static int init_channel(struct ngene_channel *chan) | |||
2494 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, | 1739 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, |
2495 | &chan->hw_frontend, | 1740 | &chan->hw_frontend, |
2496 | &chan->mem_frontend, adapter); | 1741 | &chan->mem_frontend, adapter); |
2497 | if (io & NGENE_IO_TSOUT) { | ||
2498 | dvbdemux->write_to_decoder = write_to_decoder; | ||
2499 | } | ||
2500 | #ifdef NGENE_COMMAND_API | ||
2501 | dvb_register_device(adapter, &chan->command_dev, | ||
2502 | &dvbdev_command, (void *)chan, | ||
2503 | DVB_DEVICE_SEC); | ||
2504 | #endif | ||
2505 | } | 1742 | } |
2506 | 1743 | ||
2507 | if (io & NGENE_IO_TSIN) { | 1744 | if (io & NGENE_IO_TSIN) { |
@@ -2522,7 +1759,6 @@ static int init_channel(struct ngene_channel *chan) | |||
2522 | nr); | 1759 | nr); |
2523 | } | 1760 | } |
2524 | } | 1761 | } |
2525 | |||
2526 | return ret; | 1762 | return ret; |
2527 | } | 1763 | } |
2528 | 1764 | ||
@@ -2589,12 +1825,6 @@ static int __devinit ngene_probe(struct pci_dev *pci_dev, | |||
2589 | goto fail1; | 1825 | goto fail1; |
2590 | 1826 | ||
2591 | dev->i2c_current_bus = -1; | 1827 | dev->i2c_current_bus = -1; |
2592 | /* Disable analog TV decoder chips if present */ | ||
2593 | if (copy_eeprom) { | ||
2594 | i2c_copy_eeprom(&dev->channel[0].i2c_adapter, 0x50, 0x52); | ||
2595 | i2c_dump_eeprom(&dev->channel[0].i2c_adapter, 0x52); | ||
2596 | } | ||
2597 | /*i2c_check_eeprom(&dev->i2c_adapter);*/ | ||
2598 | 1828 | ||
2599 | /* Register DVB adapters and devices for both channels */ | 1829 | /* Register DVB adapters and devices for both channels */ |
2600 | if (init_channels(dev) < 0) | 1830 | if (init_channels(dev) < 0) |
diff --git a/drivers/media/dvb/ngene/ngene-ioctls.h b/drivers/media/dvb/ngene/ngene-ioctls.h deleted file mode 100644 index 4aa2f64a5314..000000000000 --- a/drivers/media/dvb/ngene/ngene-ioctls.h +++ /dev/null | |||
@@ -1,216 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2007 Micronas | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * version 2 only, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
18 | * 02110-1301, USA | ||
19 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
20 | */ | ||
21 | |||
22 | #ifndef _NGENE_IOCTLS_H_ | ||
23 | #define _NGENE_IOCTLS_H_ | ||
24 | |||
25 | #include <linux/ioctl.h> | ||
26 | #include <linux/types.h> | ||
27 | |||
28 | #define NGENE_MAGIC 'n' | ||
29 | |||
30 | typedef struct { | ||
31 | unsigned char I2CAddress; | ||
32 | unsigned char OutLength; /* bytes to write first */ | ||
33 | unsigned char InLength; /* bytes to read */ | ||
34 | unsigned char OutData[256]; /* output data */ | ||
35 | unsigned char InData[256]; /* input data */ | ||
36 | } MIC_I2C_READ, *PMIC_I2C_READ; | ||
37 | |||
38 | #define IOCTL_MIC_I2C_READ _IOWR(NGENE_MAGIC, 0x00, MIC_I2C_READ) | ||
39 | |||
40 | |||
41 | typedef struct { | ||
42 | unsigned char I2CAddress; | ||
43 | unsigned char Length; | ||
44 | unsigned char Data[250]; | ||
45 | } MIC_I2C_WRITE, *PMIC_I2C_WRITE; | ||
46 | |||
47 | typedef struct { | ||
48 | unsigned char Length; | ||
49 | unsigned char Data[250]; | ||
50 | } MIC_I2C_CONTINUE_WRITE, *PMIC_I2C_CONTINUE_WRITE; | ||
51 | |||
52 | #define IOCTL_MIC_I2C_WRITE _IOW(NGENE_MAGIC, 0x01, \ | ||
53 | MIC_I2C_WRITE) | ||
54 | #define IOCTL_MIC_I2C_WRITE_NOSTOP _IOW(NGENE_MAGIC, 0x0c, \ | ||
55 | MIC_I2C_WRITE) | ||
56 | #define IOCTL_MIC_I2C_CONTINUE_WRITE_NOSTOP _IOW(NGENE_MAGIC, 0x0d, \ | ||
57 | MIC_I2C_CONTINUE_WRITE) | ||
58 | #define IOCTL_MIC_I2C_CONTINUE_WRITE _IOW(NGENE_MAGIC, 0x0e, \ | ||
59 | MIC_I2C_CONTINUE_WRITE) | ||
60 | |||
61 | typedef struct { | ||
62 | unsigned char ModeSelect; /* see bellow */ | ||
63 | unsigned char OutLength; /* bytes to write first */ | ||
64 | unsigned char InLength; /* bytes to read */ | ||
65 | unsigned char OutData[250]; /* output data */ | ||
66 | } MIC_SPI_READ, *PMIC_SPI_READ; | ||
67 | |||
68 | #define IOCTL_MIC_SPI_READ _IOWR(NGENE_MAGIC, 0x02, MIC_SPI_READ) | ||
69 | |||
70 | typedef struct { | ||
71 | unsigned char ModeSelect; /* see below */ | ||
72 | unsigned char Length; | ||
73 | unsigned char Data[250]; | ||
74 | } MIC_SPI_WRITE, *PMIC_SPI_WRITE; | ||
75 | |||
76 | #define IOCTL_MIC_SPI_WRITE _IOW(NGENE_MAGIC, 0x03, MIC_SPI_READ) | ||
77 | |||
78 | #define IOCTL_MIC_DOWNLOAD_FIRMWARE _IOW(NGENE_MAGIC, 0x06, unsigned char) | ||
79 | |||
80 | #define IOCTL_MIC_NO_OP _IO(NGENE_MAGIC, 0x18) | ||
81 | |||
82 | #define IOCTL_MIC_TUN_RDY _IO(NGENE_MAGIC, 0x07) | ||
83 | #define IOCTL_MIC_DEC_SRATE _IOW(NGENE_MAGIC, 0x0a, int) | ||
84 | #define IOCTL_MIC_DEC_RDY _IO(NGENE_MAGIC, 0x09) | ||
85 | #define IOCTL_MIC_DEC_FREESYNC _IOW(NGENE_MAGIC, 0x08, int) | ||
86 | #define IOCTL_MIC_TUN_DETECT _IOWR(NGENE_MAGIC, 0x0b, int) | ||
87 | |||
88 | typedef struct { | ||
89 | unsigned char Stream; /* < UVI1, UVI2, or TVOUT */ | ||
90 | unsigned char Control; | ||
91 | unsigned char Mode; | ||
92 | unsigned short nLines; | ||
93 | unsigned short nBytesPerLine; | ||
94 | unsigned short nVBILines; | ||
95 | unsigned short nBytesPerVBILine; | ||
96 | } MIC_STREAM_CONTROL, *PMIC_STREAM_CONTROL; | ||
97 | |||
98 | enum MIC_STREAM_CONTROL_MODE_BITS { | ||
99 | MSC_MODE_LOOPBACK = 0x80, | ||
100 | MSC_MODE_AVLOOP = 0x40, | ||
101 | MSC_MODE_AUDIO_SPDIF = 0x20, | ||
102 | MSC_MODE_AVSYNC = 0x10, | ||
103 | MSC_MODE_TRANSPORT_STREAM = 0x08, | ||
104 | MSC_MODE_AUDIO_CAPTURE = 0x04, | ||
105 | MSC_MODE_VBI_CAPTURE = 0x02, | ||
106 | MSC_MODE_VIDEO_CAPTURE = 0x01 | ||
107 | }; | ||
108 | |||
109 | #define IOCTL_MIC_STREAM_CONTROL _IOW(NGENE_MAGIC, 0x22, MIC_STREAM_CONTROL) | ||
110 | |||
111 | typedef struct { | ||
112 | unsigned char Stream; /* < UVI1, UVI2 */ | ||
113 | unsigned int Rate; /* < Rate in 100nsec to release the buffers | ||
114 | to the stream filters */ | ||
115 | } MIC_SIMULATE_CONTROL, *PMIC_SIMULATE_CONTROL; | ||
116 | |||
117 | #define IOCTL_MIC_SIMULATE_CONTROL _IOW(NGENE_MAGIC, 0x23, \ | ||
118 | MIC_SIMULATE_CONTROL) | ||
119 | |||
120 | /* | ||
121 | * IOCTL definitions for the test driver | ||
122 | * | ||
123 | * NOTE: the test driver also supports following IOCTL defined above: | ||
124 | * IOCTL_MIC_NO_OP: | ||
125 | * IOCTL_MIC_RECEIVE_BUFFER: | ||
126 | * IOCTL_MIC_STREAM_CONTROL: | ||
127 | * IOCTL_MIC_I2C_READ: | ||
128 | * IOCTL_MIC_I2C_WRITE: | ||
129 | * | ||
130 | * | ||
131 | * VI2C access to NGene memory (read) | ||
132 | * | ||
133 | * GETMEM in : ULONG start offset | ||
134 | * out : read data (length defined by size of output buffer) | ||
135 | * SETMEM in : ULONG start offset followed by data to be written | ||
136 | * (length defined by size of input buffer) | ||
137 | */ | ||
138 | |||
139 | typedef struct { | ||
140 | __u32 Start; | ||
141 | __u32 Length; | ||
142 | __u8 *Data; | ||
143 | } MIC_MEM; | ||
144 | |||
145 | #define IOCTL_MIC_TEST_GETMEM _IOWR(NGENE_MAGIC, 0x90, MIC_MEM) | ||
146 | #define IOCTL_MIC_TEST_SETMEM _IOW(NGENE_MAGIC, 0x91, MIC_MEM) | ||
147 | |||
148 | typedef struct { | ||
149 | __u8 Address; | ||
150 | __u8 Data; | ||
151 | } MIC_IMEM; | ||
152 | |||
153 | #define IOCTL_MIC_SFR_READ _IOWR(NGENE_MAGIC, 0xa2, MIC_IMEM) | ||
154 | #define IOCTL_MIC_SFR_WRITE _IOWR(NGENE_MAGIC, 0xa3, MIC_IMEM) | ||
155 | |||
156 | #define IOCTL_MIC_IRAM_READ _IOWR(NGENE_MAGIC, 0xa4, MIC_IMEM) | ||
157 | #define IOCTL_MIC_IRAM_WRITE _IOWR(NGENE_MAGIC, 0xa5, MIC_IMEM) | ||
158 | |||
159 | /* | ||
160 | * Set Ngene gpio bit | ||
161 | */ | ||
162 | typedef struct { | ||
163 | unsigned char Select; | ||
164 | unsigned char Level; | ||
165 | } MIC_SET_GPIO_PIN, *PMIC_SET_GPIO_PIN; | ||
166 | |||
167 | #define IOCTL_MIC_SET_GPIO_PIN _IOWR(NGENE_MAGIC, 0xa6, MIC_SET_GPIO_PIN) | ||
168 | |||
169 | /* | ||
170 | * Uart ioctls: | ||
171 | * These are implemented in the test driver. | ||
172 | * | ||
173 | * Enable UART | ||
174 | * | ||
175 | * In: 1 byte containing baud rate: 0 = 19200, 1 = 9600, 2 = 4800, 3 = 2400 | ||
176 | * Out: nothing | ||
177 | */ | ||
178 | #define IOCTL_MIC_UART_ENABLE _IOW(NGENE_MAGIC, 0xa9, unsigned char) | ||
179 | |||
180 | /* | ||
181 | * Enable UART | ||
182 | * | ||
183 | * In: nothing | ||
184 | * Out: nothing | ||
185 | */ | ||
186 | #define IOCTL_MIC_UART_DISABLE _IO(NGENE_MAGIC, 0xAA) | ||
187 | |||
188 | /* | ||
189 | * Write UART | ||
190 | * | ||
191 | * In: data to write | ||
192 | * Out: nothing | ||
193 | * Note: Call returns immediatly, data are send out asynchrounsly | ||
194 | */ | ||
195 | #define IOCTL_MIC_UART_WRITE _IOW(NGENE_MAGIC, 0xAB, unsigned char) | ||
196 | |||
197 | /* | ||
198 | * Read UART | ||
199 | * | ||
200 | * In: nothing | ||
201 | * Out: Data read (since last call) | ||
202 | * Note: Call returns immediatly | ||
203 | */ | ||
204 | #define IOCTL_MIC_UART_READ _IOR(NGENE_MAGIC, 0xAC, unsigned char) | ||
205 | |||
206 | /* | ||
207 | * UART Status | ||
208 | * | ||
209 | * In: nothing | ||
210 | * Out: Byte 0 : Transmitter busy, | ||
211 | * Byte 1 : Nbr of characters available for read. | ||
212 | * Note: Call returns immediatly | ||
213 | */ | ||
214 | #define IOCTL_MIC_UART_STATUS _IOR(NGENE_MAGIC, 0xAD, unsigned char) | ||
215 | |||
216 | #endif | ||
diff --git a/drivers/media/dvb/ngene/ngene-snd.c b/drivers/media/dvb/ngene/ngene-snd.c deleted file mode 100644 index 1ca343236ffb..000000000000 --- a/drivers/media/dvb/ngene/ngene-snd.c +++ /dev/null | |||
@@ -1,421 +0,0 @@ | |||
1 | /* | ||
2 | * ngene_snd.c: nGene PCIe bridge driver ALSA support | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Based on the initial ALSA support port by Thomas Eschbach. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 only, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
22 | * 02110-1301, USA | ||
23 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
24 | */ | ||
25 | |||
26 | #include <linux/version.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "ngene.h" | ||
30 | #include "ngene-ioctls.h" | ||
31 | |||
32 | static int sound_dev; | ||
33 | |||
34 | /* sound module parameters (see "Module Parameters") */ | ||
35 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
36 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
37 | static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; | ||
38 | |||
39 | /****************************************************************************/ | ||
40 | /* PCM Sound Funktions ******************************************************/ | ||
41 | /****************************************************************************/ | ||
42 | |||
43 | static struct snd_pcm_hardware snd_mychip_capture_hw = { | ||
44 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), | ||
45 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
46 | .rates = (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | ||
47 | | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | ||
48 | | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000), | ||
49 | .rate_min = 11025, | ||
50 | .rate_max = 48000, | ||
51 | .channels_min = 2, | ||
52 | .channels_max = 2, | ||
53 | .buffer_bytes_max = 16384, | ||
54 | .period_bytes_min = 8192, | ||
55 | .period_bytes_max = 8192, | ||
56 | .periods_min = 1, | ||
57 | .periods_max = 2, | ||
58 | }; | ||
59 | |||
60 | /* open callback */ | ||
61 | static int snd_mychip_capture_open(struct snd_pcm_substream *substream) | ||
62 | { | ||
63 | |||
64 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
65 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
66 | |||
67 | runtime->hw = snd_mychip_capture_hw; | ||
68 | chip->substream = substream; | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | /* close callback */ | ||
73 | static int snd_mychip_capture_close(struct snd_pcm_substream *substream) | ||
74 | { | ||
75 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
76 | chip->substream = NULL; | ||
77 | return 0; | ||
78 | |||
79 | } | ||
80 | |||
81 | /* hw_params callback */ | ||
82 | static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream, | ||
83 | struct snd_pcm_hw_params *hw_params) | ||
84 | { | ||
85 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
86 | struct ngene_channel *chan = chip->chan; | ||
87 | if (chan->soundbuffisallocated == 0) { | ||
88 | chan->soundbuffisallocated = 1; | ||
89 | return snd_pcm_lib_malloc_pages(substream, | ||
90 | params_buffer_bytes(hw_params)); | ||
91 | } | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | /* hw_free callback */ | ||
96 | static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream) | ||
97 | { | ||
98 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
99 | struct ngene_channel *chan = chip->chan; | ||
100 | int retval = 0; | ||
101 | if (chan->soundbuffisallocated == 1) { | ||
102 | chan->soundbuffisallocated = 0; | ||
103 | retval = snd_pcm_lib_free_pages(substream); | ||
104 | } | ||
105 | return retval; | ||
106 | } | ||
107 | |||
108 | /* prepare callback */ | ||
109 | static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream) | ||
110 | { | ||
111 | |||
112 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
113 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
114 | struct ngene_channel *chan = chip->chan; | ||
115 | struct ngene_channel *ch = &chan->dev->channel[chan->number - 2]; | ||
116 | struct i2c_adapter *adap = &ch->i2c_adapter; | ||
117 | |||
118 | if (ch->soundstreamon == 1) | ||
119 | ;/*ngene_command_stream_control_sound(chan->dev, chan->number, | ||
120 | 0x00, 0x00);*/ | ||
121 | i2c_clients_command(adap, IOCTL_MIC_DEC_SRATE, &(runtime->rate)); | ||
122 | mdelay(80); | ||
123 | if (ch->soundstreamon == 1) | ||
124 | ;/*ngene_command_stream_control_sound(chan->dev, chan->number, | ||
125 | 0x80, 0x04);*/ | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | /* trigger callback */ | ||
131 | static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
132 | { | ||
133 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
134 | struct ngene_channel *chan = chip->chan; | ||
135 | |||
136 | switch (cmd) { | ||
137 | case SNDRV_PCM_TRIGGER_START: | ||
138 | /* do something to start the PCM engine */ | ||
139 | chan->sndbuffflag = 0; | ||
140 | break; | ||
141 | case SNDRV_PCM_TRIGGER_STOP: | ||
142 | /* do something to stop the PCM engine */ | ||
143 | chip->substream = NULL; | ||
144 | chan->sndbuffflag = 0; | ||
145 | break; | ||
146 | default: | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | /* pointer callback */ | ||
153 | static snd_pcm_uframes_t | ||
154 | snd_mychip_pcm_pointer(struct snd_pcm_substream *substream) | ||
155 | { | ||
156 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
157 | struct ngene_channel *chan = chip->chan; | ||
158 | unsigned int current_ptr; | ||
159 | |||
160 | if (chan->sndbuffflag == 0) { | ||
161 | current_ptr = (unsigned int) | ||
162 | bytes_to_frames(substream->runtime, 0); | ||
163 | } else { | ||
164 | current_ptr = (unsigned int) | ||
165 | bytes_to_frames(substream->runtime, 8192); | ||
166 | } | ||
167 | return current_ptr; | ||
168 | } | ||
169 | |||
170 | /*copy sound buffer to pcm middel layer*/ | ||
171 | static int snd_capture_copy(struct snd_pcm_substream *substream, int channel, | ||
172 | snd_pcm_uframes_t pos, void *dst, | ||
173 | snd_pcm_uframes_t count) | ||
174 | { | ||
175 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
176 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
177 | struct ngene_channel *chan = chip->chan; | ||
178 | |||
179 | memcpy(dst, chan->soundbuffer, frames_to_bytes(runtime, count)); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int snd_pcm_capture_silence(struct snd_pcm_substream *substream, | ||
184 | int channel, | ||
185 | snd_pcm_uframes_t pos, | ||
186 | snd_pcm_uframes_t count) | ||
187 | { | ||
188 | /* | ||
189 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
190 | struct mychip *chip = snd_pcm_substream_chip(substream); | ||
191 | struct ngene_channel *chan = chip->chan; | ||
192 | */ | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | /* operators */ | ||
197 | static struct snd_pcm_ops snd_mychip_capture_ops = { | ||
198 | .open = snd_mychip_capture_open, | ||
199 | .close = snd_mychip_capture_close, | ||
200 | .ioctl = snd_pcm_lib_ioctl, | ||
201 | .hw_params = snd_mychip_pcm_hw_params, | ||
202 | .hw_free = snd_mychip_pcm_hw_free, | ||
203 | .prepare = snd_mychip_pcm_prepare, | ||
204 | .trigger = snd_mychip_pcm_trigger, | ||
205 | .pointer = snd_mychip_pcm_pointer, | ||
206 | .copy = snd_capture_copy, | ||
207 | .silence = snd_pcm_capture_silence, | ||
208 | }; | ||
209 | |||
210 | static void mychip_pcm_free(struct snd_pcm *pcm) | ||
211 | { | ||
212 | pcm->private_data = NULL; | ||
213 | } | ||
214 | |||
215 | /* create a pcm device */ | ||
216 | static int snd_mychip_new_pcm(struct mychip *chip, struct ngene_channel *chan) | ||
217 | { | ||
218 | struct snd_pcm *pcm; | ||
219 | int err; | ||
220 | char gro[10]; | ||
221 | sprintf(gro, "PCM%d", chan->number); | ||
222 | |||
223 | err = snd_pcm_new(chip->card, gro, 0, 0, 1, &pcm); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | |||
227 | pcm->private_data = chip; | ||
228 | pcm->private_free = mychip_pcm_free; | ||
229 | |||
230 | sprintf(pcm->name, "MyPCM_%d", chan->number); | ||
231 | |||
232 | chip->pcm = pcm; | ||
233 | /* set operators */ | ||
234 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_mychip_capture_ops); | ||
235 | /* pre-allocation of buffers */ | ||
236 | |||
237 | err = snd_pcm_lib_preallocate_pages_for_all(pcm, | ||
238 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
239 | snd_dma_continuous_data( | ||
240 | GFP_KERNEL), | ||
241 | 0, 16 * 1024); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | #define ngene_VOLUME(xname, xindex, addr) \ | ||
247 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
248 | .info = snd_volume_info, \ | ||
249 | .get = snd_volume_get, .put = snd_volume_put, \ | ||
250 | .private_value = addr } | ||
251 | |||
252 | static int snd_volume_info(struct snd_kcontrol *kcontrol, | ||
253 | struct snd_ctl_elem_info *uinfo) | ||
254 | { | ||
255 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
256 | uinfo->count = 2; | ||
257 | uinfo->value.integer.min = 0; | ||
258 | uinfo->value.integer.max = 20; | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int snd_volume_get(struct snd_kcontrol *kcontrol, | ||
263 | struct snd_ctl_elem_value *ucontrol) | ||
264 | { | ||
265 | struct mychip *chip = snd_kcontrol_chip(kcontrol); | ||
266 | int addr = kcontrol->private_value; | ||
267 | |||
268 | ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0]; | ||
269 | ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1]; | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int snd_volume_put(struct snd_kcontrol *kcontrol, | ||
274 | struct snd_ctl_elem_value *ucontrol) | ||
275 | { | ||
276 | struct mychip *chip = snd_kcontrol_chip(kcontrol); | ||
277 | int change, addr = kcontrol->private_value; | ||
278 | int left, right; | ||
279 | |||
280 | left = ucontrol->value.integer.value[0]; | ||
281 | if (left < 0) | ||
282 | left = 0; | ||
283 | if (left > 20) | ||
284 | left = 20; | ||
285 | right = ucontrol->value.integer.value[1]; | ||
286 | if (right < 0) | ||
287 | right = 0; | ||
288 | if (right > 20) | ||
289 | right = 20; | ||
290 | spin_lock_irq(&chip->mixer_lock); | ||
291 | change = chip->mixer_volume[addr][0] != left || | ||
292 | chip->mixer_volume[addr][1] != right; | ||
293 | chip->mixer_volume[addr][0] = left; | ||
294 | chip->mixer_volume[addr][1] = right; | ||
295 | spin_unlock_irq(&chip->mixer_lock); | ||
296 | return change; | ||
297 | } | ||
298 | |||
299 | #define ngene_CAPSRC(xname, xindex, addr) \ | ||
300 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ | ||
301 | .info = snd_capsrc_info, \ | ||
302 | .get = snd_capsrc_get, .put = snd_capsrc_put, \ | ||
303 | .private_value = addr } | ||
304 | |||
305 | static int snd_capsrc_info(struct snd_kcontrol *kcontrol, | ||
306 | struct snd_ctl_elem_info *uinfo) | ||
307 | { | ||
308 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
309 | uinfo->count = 2; | ||
310 | uinfo->value.integer.min = 0; | ||
311 | uinfo->value.integer.max = 1; | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int snd_capsrc_get(struct snd_kcontrol *kcontrol, | ||
316 | struct snd_ctl_elem_value *ucontrol) | ||
317 | { | ||
318 | struct mychip *chip = snd_kcontrol_chip(kcontrol); | ||
319 | int addr = kcontrol->private_value; | ||
320 | |||
321 | spin_lock_irq(&chip->mixer_lock); | ||
322 | ucontrol->value.integer.value[0] = chip->capture_source[addr][0]; | ||
323 | ucontrol->value.integer.value[1] = chip->capture_source[addr][1]; | ||
324 | spin_unlock_irq(&chip->mixer_lock); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int snd_capsrc_put(struct snd_kcontrol *kcontrol, | ||
330 | struct snd_ctl_elem_value *ucontrol) | ||
331 | { | ||
332 | struct mychip *chip = snd_kcontrol_chip(kcontrol); | ||
333 | int change, addr = kcontrol->private_value; | ||
334 | int left, right; | ||
335 | |||
336 | left = ucontrol->value.integer.value[0] & 1; | ||
337 | right = ucontrol->value.integer.value[1] & 1; | ||
338 | spin_lock_irq(&chip->mixer_lock); | ||
339 | |||
340 | change = chip->capture_source[addr][0] != left || | ||
341 | chip->capture_source[addr][1] != right; | ||
342 | chip->capture_source[addr][0] = left; | ||
343 | chip->capture_source[addr][1] = right; | ||
344 | |||
345 | spin_unlock_irq(&chip->mixer_lock); | ||
346 | |||
347 | if (change) | ||
348 | printk(KERN_INFO "snd_capsrc_put change\n"); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static struct snd_kcontrol_new snd_controls[] = { | ||
353 | ngene_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER), | ||
354 | ngene_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER), | ||
355 | }; | ||
356 | |||
357 | static int snd_card_new_mixer(struct mychip *chip) | ||
358 | { | ||
359 | struct snd_card *card = chip->card; | ||
360 | unsigned int idx; | ||
361 | int err; | ||
362 | |||
363 | strcpy(card->mixername, "NgeneMixer"); | ||
364 | |||
365 | for (idx = 0; idx < ARRAY_SIZE(snd_controls); idx++) { | ||
366 | err = snd_ctl_add(card, snd_ctl_new1(&snd_controls[idx], chip)); | ||
367 | if (err < 0) | ||
368 | return err; | ||
369 | } | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | int ngene_snd_init(struct ngene_channel *chan) | ||
374 | { | ||
375 | struct snd_card *card; | ||
376 | struct mychip *chip; | ||
377 | int err; | ||
378 | |||
379 | if (sound_dev >= SNDRV_CARDS) | ||
380 | return -ENODEV; | ||
381 | if (!enable[sound_dev]) { | ||
382 | sound_dev++; | ||
383 | return -ENOENT; | ||
384 | } | ||
385 | card = snd_card_new(index[sound_dev], id[sound_dev], | ||
386 | THIS_MODULE, sizeof(struct mychip)); | ||
387 | if (card == NULL) | ||
388 | return -ENOMEM; | ||
389 | |||
390 | chip = card->private_data; | ||
391 | chip->card = card; | ||
392 | chip->irq = -1; | ||
393 | |||
394 | sprintf(card->shortname, "MyChip%d%d", chan->dev->nr, chan->number); | ||
395 | sprintf(card->shortname, "Myown%d%d", chan->dev->nr, chan->number); | ||
396 | sprintf(card->longname, "My first Own Chip on Card Nr.%d is %d", | ||
397 | chan->dev->nr, chan->number); | ||
398 | |||
399 | spin_lock_init(&chip->lock); | ||
400 | spin_lock_init(&chip->mixer_lock); | ||
401 | |||
402 | snd_card_new_mixer(chip); | ||
403 | |||
404 | snd_mychip_new_pcm(chip, chan); | ||
405 | err = snd_card_register(card); | ||
406 | if (err < 0) { | ||
407 | snd_card_free(card); | ||
408 | return err; | ||
409 | } | ||
410 | chan->soundcard = card; | ||
411 | chan->mychip = chip; | ||
412 | chip->chan = chan; | ||
413 | sound_dev++; | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | int ngene_snd_exit(struct ngene_channel *chan) | ||
418 | { | ||
419 | snd_card_free(chan->soundcard); | ||
420 | return 0; | ||
421 | } | ||
diff --git a/drivers/media/dvb/ngene/ngene-v4l2.c b/drivers/media/dvb/ngene/ngene-v4l2.c deleted file mode 100644 index c0a9147c44a5..000000000000 --- a/drivers/media/dvb/ngene/ngene-v4l2.c +++ /dev/null | |||
@@ -1,1937 +0,0 @@ | |||
1 | /* | ||
2 | * ngene_v4l2.c: nGene PCIe bridge driver V4L2 support | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Based on the initial V4L2 support port by Thomas Eschbach. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 only, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
22 | * 02110-1301, USA | ||
23 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/unistd.h> | ||
33 | #include <linux/time.h> | ||
34 | #include <linux/pci.h> | ||
35 | #include <linux/vmalloc.h> | ||
36 | #include <linux/pagemap.h> | ||
37 | #include <linux/videodev2.h> | ||
38 | #include <linux/videodev.h> | ||
39 | #include <linux/version.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | #include <asm/semaphore.h> | ||
42 | #include <asm/system.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <asm/kmap_types.h> | ||
45 | #include <linux/videodev.h> | ||
46 | |||
47 | #include <media/v4l2-dev.h> | ||
48 | |||
49 | #include "ngene.h" | ||
50 | #include "ngene-ioctls.h" | ||
51 | |||
52 | /****************************************************************************/ | ||
53 | |||
54 | static unsigned int gbuffers = 8; | ||
55 | static unsigned int gbufsize = 0x208000; | ||
56 | |||
57 | enum km_type ngene_km_types[] = { | ||
58 | KM_USER0, | ||
59 | KM_USER1, | ||
60 | KM_SOFTIRQ0, | ||
61 | KM_SOFTIRQ1, | ||
62 | }; | ||
63 | |||
64 | #define V4L2_STD_NTSC_M_KOREA ((v4l2_std_id)0x00004000) | ||
65 | #define V4L2_STD_SECAM_L1 ((v4l2_std_id)0x00008000) | ||
66 | |||
67 | static inline void *my_video_get_drvdata(struct video_device *vd) | ||
68 | { | ||
69 | return dev_get_drvdata(vd->dev); | ||
70 | } | ||
71 | |||
72 | static inline void my_video_set_drvdata(struct video_device *vd, void *d) | ||
73 | { | ||
74 | dev_set_drvdata(vd->dev, d); | ||
75 | } | ||
76 | |||
77 | static struct ngene_tvnorm ngene_tvnorms_hd[] = { | ||
78 | { | ||
79 | .v4l2_id = V4L2_STD_PAL_BG, | ||
80 | .name = "1080i50", | ||
81 | .swidth = 1920, | ||
82 | .sheight = 1080, | ||
83 | .tuner_norm = 1, | ||
84 | .soundstd = 1, | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | static struct ngene_tvnorm ngene_tvnorms_sd[] = { | ||
89 | /* PAL-BDGHI */ | ||
90 | /* max. active video is actually 922, but 924 is divisible by 4 & 3!*/ | ||
91 | /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ | ||
92 | { | ||
93 | .v4l2_id = V4L2_STD_PAL_BG, | ||
94 | .name = "PAL-BG", | ||
95 | .swidth = 720, | ||
96 | .sheight = 576, | ||
97 | .tuner_norm = 1, | ||
98 | .soundstd = 1, | ||
99 | }, { | ||
100 | .v4l2_id = V4L2_STD_PAL_DK, | ||
101 | .name = "PAL-DK", | ||
102 | .swidth = 720, | ||
103 | .sheight = 576, | ||
104 | .tuner_norm = 2, | ||
105 | .soundstd = 2, | ||
106 | }, { | ||
107 | .v4l2_id = V4L2_STD_PAL_H, | ||
108 | .name = "PAL-H", | ||
109 | .swidth = 720, | ||
110 | .sheight = 576, | ||
111 | .tuner_norm = 0, | ||
112 | .soundstd = 1, | ||
113 | }, { | ||
114 | .v4l2_id = V4L2_STD_PAL_I, | ||
115 | .name = "PAL-I", | ||
116 | .swidth = 720, | ||
117 | .sheight = 576, | ||
118 | .tuner_norm = 4, | ||
119 | .soundstd = 4, | ||
120 | }, { | ||
121 | .v4l2_id = V4L2_STD_PAL_M, | ||
122 | .name = "PAL_M", | ||
123 | .swidth = 720, | ||
124 | .sheight = 5760, | ||
125 | .tuner_norm = 7, | ||
126 | .soundstd = 5, | ||
127 | }, { | ||
128 | .v4l2_id = V4L2_STD_NTSC_M, | ||
129 | .name = "NTSC_M", | ||
130 | .swidth = 720, | ||
131 | .sheight = 480, | ||
132 | .tuner_norm = 7, | ||
133 | .soundstd = 5, | ||
134 | }, { | ||
135 | .v4l2_id = V4L2_STD_NTSC_M_JP, | ||
136 | .name = "NTSC_M_JP", | ||
137 | .swidth = 720, | ||
138 | .sheight = 480, | ||
139 | .tuner_norm = 7, | ||
140 | .soundstd = 6, | ||
141 | }, { | ||
142 | .v4l2_id = V4L2_STD_PAL_N, | ||
143 | .name = "PAL-N", | ||
144 | .swidth = 720, | ||
145 | .sheight = 576, | ||
146 | .tuner_norm = 7, | ||
147 | .soundstd = 5, | ||
148 | }, { | ||
149 | .v4l2_id = V4L2_STD_SECAM_B, | ||
150 | .name = "SECAM_B", | ||
151 | .swidth = 720, | ||
152 | .sheight = 576, | ||
153 | .tuner_norm = 1, | ||
154 | .soundstd = 1, | ||
155 | }, { | ||
156 | .v4l2_id = V4L2_STD_SECAM_D, | ||
157 | .name = "SECAM_D", | ||
158 | .swidth = 720, | ||
159 | .sheight = 576, | ||
160 | .tuner_norm = 2, | ||
161 | .soundstd = 2, | ||
162 | }, { | ||
163 | .v4l2_id = V4L2_STD_SECAM_G, | ||
164 | .name = "SECAM_G", | ||
165 | .swidth = 720, | ||
166 | .sheight = 576, | ||
167 | .tuner_norm = 3, | ||
168 | .soundstd = 1, | ||
169 | }, { | ||
170 | .v4l2_id = V4L2_STD_SECAM_H, | ||
171 | .name = "SECAM_H", | ||
172 | .swidth = 720, | ||
173 | .sheight = 576, | ||
174 | .tuner_norm = 3, | ||
175 | .soundstd = 1, | ||
176 | }, { | ||
177 | .v4l2_id = V4L2_STD_SECAM_K, | ||
178 | .name = "SECAM_K", | ||
179 | .swidth = 720, | ||
180 | .sheight = 576, | ||
181 | .tuner_norm = 2, | ||
182 | .soundstd = 2, | ||
183 | }, { | ||
184 | .v4l2_id = V4L2_STD_SECAM_K1, | ||
185 | .name = "SECAM_K1", | ||
186 | .swidth = 720, | ||
187 | .sheight = 576, | ||
188 | .tuner_norm = 2, | ||
189 | .soundstd = 2, | ||
190 | }, { | ||
191 | .v4l2_id = V4L2_STD_SECAM_L, | ||
192 | .name = "SECAM_L", | ||
193 | .swidth = 720, | ||
194 | .sheight = 576, | ||
195 | .tuner_norm = 5, | ||
196 | .soundstd = 3, | ||
197 | }, { | ||
198 | .v4l2_id = V4L2_STD_NTSC_M_KOREA, | ||
199 | .name = "NTSC_M_KOREA", | ||
200 | .swidth = 720, | ||
201 | .sheight = 480, | ||
202 | .tuner_norm = 7, | ||
203 | .soundstd = 7, | ||
204 | }, { | ||
205 | .v4l2_id = V4L2_STD_SECAM_L1, | ||
206 | .name = "SECAM_L1", | ||
207 | .swidth = 720, | ||
208 | .sheight = 576, | ||
209 | .tuner_norm = 6, | ||
210 | .soundstd = 3, | ||
211 | } | ||
212 | |||
213 | }; | ||
214 | |||
215 | static const int NGENE_TVNORMS = ARRAY_SIZE(ngene_tvnorms_sd); | ||
216 | |||
217 | static u8 BlackLine[1440] = { | ||
218 | /* 0x80, */ 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
219 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
220 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
221 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
222 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
223 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
224 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
225 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
226 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
227 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
228 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
229 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
230 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
231 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
232 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
233 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
234 | |||
235 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
236 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
237 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
238 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
239 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
240 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
241 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
242 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
243 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
244 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
245 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
246 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
247 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
248 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
249 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
250 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
251 | |||
252 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
253 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
254 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
255 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
256 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
257 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
258 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
259 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
260 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
261 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
262 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
263 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
264 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
265 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
266 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
267 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
268 | |||
269 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
270 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
271 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
272 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
273 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
274 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
275 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
276 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
277 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
278 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
279 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
280 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
281 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
282 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
283 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
284 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
285 | |||
286 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
287 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
288 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
289 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
290 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
291 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
292 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
293 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
294 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
295 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
296 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
297 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
298 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
299 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
300 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
301 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
302 | |||
303 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
304 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
305 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
306 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
307 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
308 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
309 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
310 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
311 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
312 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
313 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
314 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
315 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
316 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
317 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
318 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
319 | |||
320 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
321 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
322 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
323 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
324 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
325 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
326 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
327 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
328 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
329 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
330 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
331 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
332 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
333 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
334 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
335 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
336 | |||
337 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
338 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
339 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
340 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
341 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
342 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
343 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
344 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
345 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
346 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
347 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
348 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
349 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
350 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
351 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
352 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
353 | |||
354 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
355 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
356 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
357 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
358 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
359 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
360 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
361 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
362 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
363 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
364 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
365 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
366 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
367 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
368 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
369 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
370 | |||
371 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
372 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
373 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
374 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
375 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
376 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
377 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
378 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
379 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
380 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
381 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
382 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
383 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
384 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
385 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
386 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
387 | |||
388 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
389 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
390 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
391 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
392 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
393 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
394 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
395 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
396 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
397 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
398 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
399 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
400 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
401 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
402 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
403 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
404 | |||
405 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
406 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
407 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
408 | 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, | ||
409 | 0x80, | ||
410 | }; | ||
411 | |||
412 | #define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0) | ||
413 | #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 1) | ||
414 | |||
415 | static const struct v4l2_queryctrl no_ctl = { | ||
416 | .name = "no_ctl", | ||
417 | .flags = V4L2_CTRL_FLAG_DISABLED, | ||
418 | }; | ||
419 | |||
420 | static const struct v4l2_queryctrl ngene_ctls[] = { | ||
421 | /* --- video --- */ | ||
422 | { | ||
423 | .id = V4L2_CID_BRIGHTNESS, | ||
424 | .name = "Brightness", | ||
425 | .minimum = -127, | ||
426 | .maximum = 127, | ||
427 | .step = 1, | ||
428 | .default_value = 0, | ||
429 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
430 | }, { | ||
431 | .id = V4L2_CID_CONTRAST, | ||
432 | .name = "Contrast", | ||
433 | .minimum = 0, | ||
434 | .maximum = 63, | ||
435 | .step = 1, | ||
436 | .default_value = 30, | ||
437 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
438 | }, { | ||
439 | .id = V4L2_CID_SATURATION, | ||
440 | .name = "Saturation", | ||
441 | .minimum = 0, | ||
442 | .maximum = 4094, | ||
443 | .step = 1, | ||
444 | .default_value = 2000, | ||
445 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
446 | }, { | ||
447 | .id = V4L2_CID_HUE, | ||
448 | .name = "Hue", | ||
449 | .minimum = -2047, | ||
450 | .maximum = 2047, | ||
451 | .step = 1, | ||
452 | .default_value = 0, | ||
453 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
454 | }, | ||
455 | /* --- audio --- */ | ||
456 | { | ||
457 | .id = V4L2_CID_AUDIO_MUTE, | ||
458 | .name = "Mute", | ||
459 | .minimum = 0, | ||
460 | .maximum = 1, | ||
461 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
462 | }, { | ||
463 | .id = V4L2_CID_PRIVATE_SHARPNESS, | ||
464 | .name = "sharpness", | ||
465 | .minimum = 0, | ||
466 | .maximum = 100, | ||
467 | .step = 1, | ||
468 | .default_value = 50, | ||
469 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
470 | }, | ||
471 | |||
472 | }; | ||
473 | |||
474 | static const int NGENE_CTLS = ARRAY_SIZE(ngene_ctls); | ||
475 | |||
476 | static const struct ngene_format ngene_formats[] = { | ||
477 | { | ||
478 | .name = "4:2:2, packed, YUYV", | ||
479 | .palette = -1, | ||
480 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
481 | .format = V4L2_PIX_FMT_YUYV, | ||
482 | .palette = VIDEO_PALETTE_YUYV, | ||
483 | .depth = 16, | ||
484 | .flags = 0x02,/* FORMAT_FLAGS_PACKED, */ | ||
485 | } | ||
486 | }; | ||
487 | |||
488 | static const unsigned int NGENE_FORMATS = ARRAY_SIZE(ngene_formats); | ||
489 | |||
490 | /****************************************************************************/ | ||
491 | |||
492 | static struct videobuf_queue *ngene_queue(struct ngene_vopen *vopen) | ||
493 | { | ||
494 | struct videobuf_queue *q = NULL; | ||
495 | |||
496 | switch (vopen->type) { | ||
497 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
498 | q = &vopen->vbuf_q; | ||
499 | break; | ||
500 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
501 | q = &vopen->vbi; | ||
502 | break; | ||
503 | default: | ||
504 | break; | ||
505 | } | ||
506 | return q; | ||
507 | } | ||
508 | |||
509 | static int ngene_resource(struct ngene_vopen *vopen) | ||
510 | { | ||
511 | int res = 0; | ||
512 | |||
513 | switch (vopen->type) { | ||
514 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
515 | res = RESOURCE_VIDEO; | ||
516 | break; | ||
517 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
518 | res = RESOURCE_VBI; | ||
519 | break; | ||
520 | default: | ||
521 | break; | ||
522 | } | ||
523 | return res; | ||
524 | } | ||
525 | |||
526 | static int ngene_try_fmt(struct ngene_vopen *vopen, struct ngene_channel *chan, | ||
527 | struct v4l2_format *f) | ||
528 | { | ||
529 | switch (f->type) { | ||
530 | |||
531 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
532 | { | ||
533 | const struct ngene_format *fmt; | ||
534 | enum v4l2_field field; | ||
535 | unsigned int maxw, maxh; | ||
536 | int maxLinesPerField; | ||
537 | |||
538 | fmt = ngene_formats; | ||
539 | if (NULL == fmt) | ||
540 | return -EINVAL; | ||
541 | |||
542 | /* fixup format */ | ||
543 | maxw = chan->tvnorms[chan->tvnorm].swidth; | ||
544 | maxLinesPerField = chan->tvnorms[chan->tvnorm].sheight; | ||
545 | maxh = maxLinesPerField; | ||
546 | field = f->fmt.pix.field; | ||
547 | |||
548 | if (V4L2_FIELD_ANY == field) | ||
549 | field = (f->fmt.pix.height > maxh / 2) | ||
550 | ? V4L2_FIELD_INTERLACED : V4L2_FIELD_BOTTOM; | ||
551 | |||
552 | if (V4L2_FIELD_SEQ_BT == field) | ||
553 | field = V4L2_FIELD_SEQ_TB; | ||
554 | |||
555 | /* update data for the application */ | ||
556 | f->fmt.pix.field = field; | ||
557 | if (f->fmt.pix.width < 48) | ||
558 | f->fmt.pix.width = 48; | ||
559 | if (f->fmt.pix.height < 32) | ||
560 | f->fmt.pix.height = 32; | ||
561 | if (f->fmt.pix.width > maxw) | ||
562 | f->fmt.pix.width = maxw; | ||
563 | if (f->fmt.pix.height > maxh) | ||
564 | f->fmt.pix.height = maxh; | ||
565 | f->fmt.pix.width &= ~0x03; | ||
566 | f->fmt.pix.bytesperline = | ||
567 | (f->fmt.pix.width * fmt->depth) >> 3; | ||
568 | f->fmt.pix.sizeimage = | ||
569 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
575 | return -EINVAL; | ||
576 | |||
577 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
578 | return 0; | ||
579 | |||
580 | default: | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | /****************************************************************************/ | ||
586 | /* Analog driver stuff ******************************************************/ | ||
587 | /****************************************************************************/ | ||
588 | |||
589 | static int check_alloc_res(struct ngene_channel *channel, | ||
590 | struct ngene_vopen *vopen, int bit) | ||
591 | { | ||
592 | if (vopen->resources & bit) | ||
593 | /* have it already allocated */ | ||
594 | return 1; | ||
595 | |||
596 | /* is it free? */ | ||
597 | down(&channel->reslock); | ||
598 | if (channel->resources & bit) { | ||
599 | /* no, someone else uses it */ | ||
600 | up(&channel->reslock); | ||
601 | return 0; | ||
602 | } | ||
603 | /* it's free, grab it */ | ||
604 | vopen->resources |= bit; | ||
605 | channel->resources |= bit; | ||
606 | up(&channel->reslock); | ||
607 | return 1; | ||
608 | } | ||
609 | |||
610 | static int check_res(struct ngene_vopen *vopen, int bit) | ||
611 | { | ||
612 | return vopen->resources & bit; | ||
613 | } | ||
614 | |||
615 | static int locked_res(struct ngene_channel *chan, int bit) | ||
616 | { | ||
617 | return chan->resources & bit; | ||
618 | } | ||
619 | |||
620 | static void free_res(struct ngene_channel *channel, | ||
621 | struct ngene_vopen *vopen, int bits) | ||
622 | { | ||
623 | down(&channel->reslock); | ||
624 | vopen->resources &= ~bits; | ||
625 | channel->resources &= ~bits; | ||
626 | up(&channel->reslock); | ||
627 | } | ||
628 | |||
629 | /****************************************************************************/ | ||
630 | /* MISC HELPERS *************************************************************/ | ||
631 | /****************************************************************************/ | ||
632 | |||
633 | static int ngene_g_fmt(struct ngene_vopen *vopen, struct v4l2_format *f) | ||
634 | { | ||
635 | if (!vopen->fmt) | ||
636 | vopen->fmt = ngene_formats; | ||
637 | |||
638 | switch (f->type) { | ||
639 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
640 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); | ||
641 | f->fmt.pix.width = vopen->width; | ||
642 | f->fmt.pix.height = vopen->height; | ||
643 | f->fmt.pix.field = vopen->vbuf_q.field; | ||
644 | f->fmt.pix.pixelformat = vopen->fmt->fourcc; | ||
645 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 16) >> 3; | ||
646 | f->fmt.pix.sizeimage = | ||
647 | f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
648 | return 0; | ||
649 | |||
650 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
651 | memset(&f->fmt.win, 0, sizeof(struct v4l2_window)); | ||
652 | return 0; | ||
653 | f->fmt.win.w = vopen->ov.w; | ||
654 | f->fmt.win.field = vopen->ov.field; | ||
655 | return 0; | ||
656 | |||
657 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
658 | return -EINVAL; | ||
659 | |||
660 | default: | ||
661 | return -EINVAL; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static int ngene_switch_type(struct ngene_vopen *vopen, enum v4l2_buf_type type) | ||
666 | { | ||
667 | struct videobuf_queue *q = ngene_queue(vopen); | ||
668 | int res = ngene_resource(vopen); | ||
669 | |||
670 | if (check_res(vopen, res)) | ||
671 | return -EBUSY; | ||
672 | if (videobuf_queue_is_busy(q)) | ||
673 | return -EBUSY; | ||
674 | vopen->type = type; | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | static int ngene_s_fmt(struct ngene_vopen *vopen, struct ngene_channel *chan, | ||
679 | struct v4l2_format *f) | ||
680 | { | ||
681 | int retval; | ||
682 | |||
683 | switch (f->type) { | ||
684 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
685 | { | ||
686 | const struct ngene_format *fmt; | ||
687 | retval = ngene_try_fmt(vopen, chan, f); | ||
688 | if (0 != retval) | ||
689 | return retval; | ||
690 | |||
691 | retval = ngene_switch_type(vopen, f->type); | ||
692 | if (0 != retval) | ||
693 | return retval; | ||
694 | fmt = ngene_formats; | ||
695 | |||
696 | if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) | ||
697 | return -EINVAL; | ||
698 | /* update our state informations */ | ||
699 | mutex_lock(&vopen->vbuf_q.lock); | ||
700 | vopen->fmt = fmt; | ||
701 | vopen->vbuf_q.field = f->fmt.pix.field; | ||
702 | vopen->vbuf_q.last = V4L2_FIELD_INTERLACED; | ||
703 | vopen->width = f->fmt.pix.width; | ||
704 | vopen->height = f->fmt.pix.height; | ||
705 | chan->init.fmt = fmt; | ||
706 | chan->init.width = f->fmt.pix.width; | ||
707 | chan->init.height = f->fmt.pix.height; | ||
708 | mutex_unlock(&vopen->vbuf_q.lock); | ||
709 | |||
710 | return 0; | ||
711 | } | ||
712 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
713 | return -EINVAL; | ||
714 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
715 | return -EINVAL; | ||
716 | default: | ||
717 | return -EINVAL; | ||
718 | } | ||
719 | } | ||
720 | |||
721 | /****************************************************************************/ | ||
722 | /* SG support ***************************************************************/ | ||
723 | /****************************************************************************/ | ||
724 | |||
725 | static inline enum km_type ngene_kmap_type(int out) | ||
726 | { | ||
727 | return ngene_km_types[(in_softirq() ? 2 : 0) + out]; | ||
728 | } | ||
729 | |||
730 | static inline void *ngene_kmap(struct page *page, int out) | ||
731 | { | ||
732 | return kmap_atomic(page, ngene_kmap_type(out)); | ||
733 | } | ||
734 | |||
735 | static inline void ngene_kunmap(void *vaddr, int out) | ||
736 | { | ||
737 | kunmap_atomic(vaddr, ngene_kmap_type(out)); | ||
738 | } | ||
739 | |||
740 | struct scatter_walk { | ||
741 | struct scatterlist *sg; | ||
742 | struct page *page; | ||
743 | void *data; | ||
744 | unsigned int len_this_page; | ||
745 | unsigned int len_this_segment; | ||
746 | unsigned int offset; | ||
747 | }; | ||
748 | |||
749 | static inline struct scatterlist *sg_next(struct scatterlist *sg) | ||
750 | { | ||
751 | return sg + 1; | ||
752 | } | ||
753 | |||
754 | void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes) | ||
755 | { | ||
756 | if (nbytes <= walk->len_this_page && | ||
757 | (((unsigned long)walk->data) & | ||
758 | (PAGE_CACHE_SIZE - 1)) + nbytes <= PAGE_CACHE_SIZE) | ||
759 | return walk->data; | ||
760 | else | ||
761 | return walk->data; | ||
762 | } | ||
763 | |||
764 | void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg) | ||
765 | { | ||
766 | unsigned int rest_of_page; | ||
767 | |||
768 | walk->sg = sg; | ||
769 | walk->page = sg->page; | ||
770 | walk->len_this_segment = sg->length; | ||
771 | rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1)); | ||
772 | walk->len_this_page = min(sg->length, rest_of_page); | ||
773 | walk->offset = sg->offset; | ||
774 | } | ||
775 | |||
776 | void scatterwalk_map(struct scatter_walk *walk, int out) | ||
777 | { | ||
778 | walk->data = ngene_kmap(walk->page, out) + walk->offset; | ||
779 | } | ||
780 | |||
781 | static void scatterwalk_pagedone(struct scatter_walk *walk, int out, | ||
782 | unsigned int more) | ||
783 | { | ||
784 | /* walk->data may be pointing the first byte of the next page; | ||
785 | however, we know we transfered at least one byte. So, | ||
786 | walk->data - 1 will be a virtual address in the mapped page. */ | ||
787 | |||
788 | if (out) | ||
789 | flush_dcache_page(walk->page); | ||
790 | |||
791 | if (more) { | ||
792 | walk->len_this_segment -= walk->len_this_page; | ||
793 | |||
794 | if (walk->len_this_segment) { | ||
795 | walk->page++; | ||
796 | walk->len_this_page = min(walk->len_this_segment, | ||
797 | (unsigned)PAGE_CACHE_SIZE); | ||
798 | walk->offset = 0; | ||
799 | } else { | ||
800 | scatterwalk_start(walk, sg_next(walk->sg)); | ||
801 | } | ||
802 | } | ||
803 | } | ||
804 | |||
805 | void scatterwalk_done(struct scatter_walk *walk, int out, int more) | ||
806 | { | ||
807 | ngene_kunmap(walk->data, out); | ||
808 | if (walk->len_this_page == 0 || !more) | ||
809 | scatterwalk_pagedone(walk, out, more); | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * Do not call this unless the total length of all of the fragments | ||
814 | * has been verified as multiple of the block size. | ||
815 | */ | ||
816 | int scatterwalk_copychunks(struct scatter_walk *walk, size_t nbytes, int out) | ||
817 | { | ||
818 | walk->offset += nbytes; | ||
819 | walk->len_this_page -= nbytes; | ||
820 | walk->len_this_segment -= nbytes; | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | static void *vid_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | ||
825 | { | ||
826 | struct ngene_channel *chan = priv; | ||
827 | struct ngene_buffer *item; | ||
828 | int wstrich, hstrich; | ||
829 | u8 *odd, *even; | ||
830 | u32 bpl = chan->tvnorms[chan->tvnorm].swidth * 2; | ||
831 | |||
832 | struct scatter_walk walk_out; | ||
833 | const unsigned int bsize = PAGE_SIZE; | ||
834 | unsigned int nbytes; | ||
835 | int rest_of_buffer, ah, rwstrich; | ||
836 | |||
837 | spin_lock(&chan->s_lock); | ||
838 | |||
839 | if (list_empty(&chan->capture)) { | ||
840 | chan->evenbuffer = NULL; | ||
841 | goto out; | ||
842 | } | ||
843 | item = list_entry(chan->capture.next, struct ngene_buffer, vb.queue); | ||
844 | |||
845 | if (chan->tvnorms[chan->tvnorm].sheight == 1080) | ||
846 | buf += 3840; | ||
847 | |||
848 | odd = buf; | ||
849 | |||
850 | hstrich = item->vb.height; | ||
851 | if (hstrich > chan->tvnorms[chan->tvnorm].sheight) | ||
852 | hstrich = chan->tvnorms[chan->tvnorm].sheight; | ||
853 | |||
854 | wstrich = item->vb.width; | ||
855 | if (wstrich > chan->tvnorms[chan->tvnorm].swidth) | ||
856 | wstrich = chan->tvnorms[chan->tvnorm].swidth; | ||
857 | wstrich <<= 1; | ||
858 | |||
859 | if (flags & BEF_EVEN_FIELD) { | ||
860 | chan->evenbuffer = buf; | ||
861 | if (chan->lastbufferflag) { | ||
862 | chan->lastbufferflag = 0; | ||
863 | if (chan->tvnorms[chan->tvnorm].sheight == 576) { | ||
864 | memcpy(buf + 413280, BlackLine, 1440); | ||
865 | memcpy(buf + 411840, BlackLine, 1440); | ||
866 | } | ||
867 | goto out; | ||
868 | } | ||
869 | } | ||
870 | chan->lastbufferflag = 1; | ||
871 | if (chan->evenbuffer) | ||
872 | even = chan->evenbuffer; | ||
873 | else | ||
874 | even = odd; | ||
875 | if (chan->tvnorms[chan->tvnorm].sheight == 576) { | ||
876 | memcpy(odd + 413280, BlackLine, 1440); | ||
877 | memcpy(odd + 411840, BlackLine, 1440); | ||
878 | } | ||
879 | nbytes = item->vb.dma.sglen * PAGE_SIZE; | ||
880 | scatterwalk_start(&walk_out, item->vb.dma.sglist); | ||
881 | ah = 0; | ||
882 | rwstrich = wstrich; | ||
883 | do { | ||
884 | u8 *dst_p; | ||
885 | |||
886 | rest_of_buffer = bsize; | ||
887 | scatterwalk_map(&walk_out, 1); | ||
888 | dst_p = scatterwalk_whichbuf(&walk_out, bsize); | ||
889 | nbytes -= bsize; | ||
890 | scatterwalk_copychunks(&walk_out, bsize, 1); | ||
891 | |||
892 | while (rest_of_buffer > 0 && ah < hstrich) { | ||
893 | if (rest_of_buffer >= rwstrich) { | ||
894 | if (ah % 2 == 0) { | ||
895 | memcpy(walk_out.data + | ||
896 | (bsize - rest_of_buffer), | ||
897 | odd, rwstrich); | ||
898 | odd += bpl - (wstrich - rwstrich); | ||
899 | } else { | ||
900 | memcpy(walk_out.data + | ||
901 | (bsize - rest_of_buffer), | ||
902 | even, rwstrich); | ||
903 | even += bpl - (wstrich - rwstrich); | ||
904 | } | ||
905 | rest_of_buffer -= rwstrich; | ||
906 | ah++; | ||
907 | rwstrich = wstrich; | ||
908 | } else { | ||
909 | if (ah % 2 == 0) { | ||
910 | memcpy(walk_out.data + | ||
911 | (bsize - rest_of_buffer), | ||
912 | odd, rest_of_buffer); | ||
913 | odd += rest_of_buffer; | ||
914 | } else { | ||
915 | memcpy(walk_out.data + | ||
916 | (bsize - rest_of_buffer), | ||
917 | even, rest_of_buffer); | ||
918 | even += rest_of_buffer; | ||
919 | } | ||
920 | rwstrich -= rest_of_buffer; | ||
921 | rest_of_buffer = 0; | ||
922 | } | ||
923 | } | ||
924 | scatterwalk_done(&walk_out, 1, nbytes); | ||
925 | } while (nbytes && ah < hstrich); | ||
926 | |||
927 | { | ||
928 | struct timeval ts; | ||
929 | do_gettimeofday(&ts); | ||
930 | list_del(&item->vb.queue); | ||
931 | item->vb.state = STATE_DONE; | ||
932 | item->vb.ts = ts; | ||
933 | wake_up(&item->vb.done); | ||
934 | chan->evenbuffer = NULL; | ||
935 | } | ||
936 | |||
937 | out: | ||
938 | spin_unlock(&chan->s_lock); | ||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | static void *snd_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | ||
943 | { | ||
944 | struct ngene_channel *chan = priv; | ||
945 | struct mychip *mychip = chan->mychip; | ||
946 | |||
947 | if (chan->audiomute == 0) | ||
948 | memcpy(chan->soundbuffer, (u8 *) buf, MAX_AUDIO_BUFFER_SIZE); | ||
949 | else | ||
950 | memset(chan->soundbuffer, 0, MAX_AUDIO_BUFFER_SIZE); | ||
951 | |||
952 | if (mychip->substream != NULL) { | ||
953 | if (chan->sndbuffflag == 0) | ||
954 | chan->sndbuffflag = 1; | ||
955 | else | ||
956 | chan->sndbuffflag = 0; | ||
957 | spin_unlock(&mychip->lock); | ||
958 | snd_pcm_period_elapsed(mychip->substream); | ||
959 | spin_lock(&mychip->lock); | ||
960 | } | ||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | static void set_analog_transfer(struct ngene_channel *chan, int state) | ||
965 | { | ||
966 | struct ngene_channel *ch; | ||
967 | u8 flags = 0; | ||
968 | |||
969 | ch = &chan->dev->channel[chan->number + 2]; | ||
970 | /* printk(KERN_INFO "set_analog_transfer %d\n", state); */ | ||
971 | |||
972 | if (1) { /* chan->tun_dec_rdy == 1){ */ | ||
973 | if (state) { | ||
974 | |||
975 | chan->Capture1Length = | ||
976 | chan->tvnorms[chan->tvnorm].swidth * | ||
977 | chan->tvnorms[chan->tvnorm].sheight; | ||
978 | if (chan->tvnorms[chan->tvnorm].sheight == 576) | ||
979 | chan->nLines = 287; | ||
980 | else if (chan->tvnorms[chan->tvnorm].sheight == 1080) | ||
981 | chan->nLines = 541; | ||
982 | else | ||
983 | chan->nLines = | ||
984 | chan->tvnorms[chan->tvnorm].sheight / 2; | ||
985 | chan->nBytesPerLine = | ||
986 | chan->tvnorms[chan->tvnorm].swidth * 2; | ||
987 | if (chan->dev->card_info->io_type[chan->number] == | ||
988 | NGENE_IO_HDTV) { | ||
989 | chan->itumode = 2; | ||
990 | flags = SFLAG_ORDER_LUMA_CHROMA; | ||
991 | } else { | ||
992 | chan->itumode = 0; | ||
993 | flags = SFLAG_ORDER_LUMA_CHROMA; | ||
994 | } | ||
995 | chan->pBufferExchange = vid_exchange; | ||
996 | ngene_command_stream_control(chan->dev, chan->number, | ||
997 | 0x80, | ||
998 | SMODE_VIDEO_CAPTURE, | ||
999 | flags); | ||
1000 | |||
1001 | ch->Capture1Length = MAX_AUDIO_BUFFER_SIZE; | ||
1002 | ch->pBufferExchange = snd_exchange; | ||
1003 | ngene_command_stream_control(ch->dev, ch->number, | ||
1004 | 0x80, | ||
1005 | SMODE_AUDIO_CAPTURE, 0); | ||
1006 | ch->soundstreamon = 1; | ||
1007 | } else { | ||
1008 | ngene_command_stream_control(chan->dev, chan->number, | ||
1009 | 0, 0, 0); | ||
1010 | ngene_command_stream_control(ch->dev, ch->number, | ||
1011 | 0, 0, 0); | ||
1012 | ch->soundstreamon = 0; | ||
1013 | } | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | static int ngene_analog_start_feed(struct ngene_channel *chan) | ||
1018 | { | ||
1019 | int freerunmode = 1; | ||
1020 | struct i2c_adapter *adapter = &chan->i2c_adapter; | ||
1021 | |||
1022 | if (chan->users == 0 && chan->number < 2) { | ||
1023 | chan->evenbuffer = NULL; | ||
1024 | chan->users = 1; | ||
1025 | i2c_clients_command(adapter, IOCTL_MIC_DEC_FREESYNC, | ||
1026 | &freerunmode); | ||
1027 | msleep(25); | ||
1028 | set_analog_transfer(chan, 1); | ||
1029 | msleep(25); | ||
1030 | freerunmode = 0; | ||
1031 | i2c_clients_command(adapter, IOCTL_MIC_DEC_FREESYNC, | ||
1032 | &freerunmode); | ||
1033 | } | ||
1034 | return chan->users; | ||
1035 | } | ||
1036 | |||
1037 | static int ngene_analog_stop_feed(struct ngene_channel *chan) | ||
1038 | { | ||
1039 | int freerunmode = 1; | ||
1040 | struct i2c_adapter *adapter = &chan->i2c_adapter; | ||
1041 | if (chan->users == 1 && chan->number < 2) { | ||
1042 | chan->users = 0; | ||
1043 | i2c_clients_command(adapter, | ||
1044 | IOCTL_MIC_DEC_FREESYNC, &freerunmode); | ||
1045 | msleep(20); | ||
1046 | set_analog_transfer(chan, 0); | ||
1047 | } | ||
1048 | return 0; | ||
1049 | } | ||
1050 | |||
1051 | /****************************************************************************/ | ||
1052 | /* V4L2 API interface *******************************************************/ | ||
1053 | /****************************************************************************/ | ||
1054 | |||
1055 | void ngene_dma_free(struct videobuf_queue *q, | ||
1056 | struct ngene_channel *chan, struct ngene_buffer *buf) | ||
1057 | { | ||
1058 | videobuf_waiton(&buf->vb, 0, 0); | ||
1059 | videobuf_dma_unmap(q, &buf->vb.dma); | ||
1060 | videobuf_dma_free(&buf->vb.dma); | ||
1061 | buf->vb.state = STATE_NEEDS_INIT; | ||
1062 | } | ||
1063 | |||
1064 | static int ngene_prepare_buffer(struct videobuf_queue *q, | ||
1065 | struct ngene_channel *chan, | ||
1066 | struct ngene_buffer *buf, | ||
1067 | const struct ngene_format *fmt, | ||
1068 | unsigned int width, unsigned int height, | ||
1069 | enum v4l2_field field) | ||
1070 | { | ||
1071 | int rc = 0; | ||
1072 | /* check settings */ | ||
1073 | if (NULL == fmt) | ||
1074 | return -EINVAL; | ||
1075 | |||
1076 | if (width < 48 || height < 32) | ||
1077 | return -EINVAL; | ||
1078 | |||
1079 | buf->vb.size = (width * height * 16 /* fmt->depth */) >> 3; | ||
1080 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
1081 | return -EINVAL; | ||
1082 | |||
1083 | /* alloc + fill struct ngene_buffer (if changed) */ | ||
1084 | if (buf->vb.width != width || buf->vb.height != height || | ||
1085 | buf->vb.field != field || buf->fmt != fmt || | ||
1086 | buf->tvnorm != chan->tvnorm) { | ||
1087 | |||
1088 | buf->vb.width = width; | ||
1089 | buf->vb.height = height; | ||
1090 | buf->vb.field = field; | ||
1091 | buf->tvnorm = chan->tvnorm; | ||
1092 | buf->fmt = fmt; | ||
1093 | |||
1094 | ngene_dma_free(q, chan, buf); | ||
1095 | } | ||
1096 | |||
1097 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
1098 | return -EINVAL; | ||
1099 | |||
1100 | if (buf->vb.field == 0) | ||
1101 | buf->vb.field = V4L2_FIELD_INTERLACED; | ||
1102 | |||
1103 | if (STATE_NEEDS_INIT == buf->vb.state) { | ||
1104 | buf->vb.width = width; | ||
1105 | buf->vb.height = height; | ||
1106 | buf->vb.field = field; | ||
1107 | buf->tvnorm = chan->tvnorm; | ||
1108 | buf->fmt = fmt; | ||
1109 | |||
1110 | rc = videobuf_iolock(q, &buf->vb, &chan->fbuf); | ||
1111 | if (0 != rc) | ||
1112 | goto fail; | ||
1113 | } | ||
1114 | if (!buf->vb.dma.bus_addr) | ||
1115 | videobuf_dma_sync(q, &buf->vb.dma); | ||
1116 | buf->vb.state = STATE_PREPARED; | ||
1117 | return 0; | ||
1118 | |||
1119 | fail: | ||
1120 | ngene_dma_free(q, chan, buf); | ||
1121 | return rc; | ||
1122 | |||
1123 | } | ||
1124 | |||
1125 | static int buffer_setup(struct videobuf_queue *q, | ||
1126 | unsigned int *count, unsigned int *size) | ||
1127 | { | ||
1128 | struct ngene_vopen *vopen = q->priv_data; | ||
1129 | *size = 2 * vopen->width * vopen->height; | ||
1130 | if (0 == *count) | ||
1131 | *count = gbuffers; | ||
1132 | while (*size * *count > gbuffers * gbufsize) | ||
1133 | (*count)--; | ||
1134 | q->field = V4L2_FIELD_INTERLACED; | ||
1135 | q->last = V4L2_FIELD_INTERLACED; | ||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
1140 | enum v4l2_field field) | ||
1141 | { | ||
1142 | struct ngene_buffer *buf = container_of(vb, struct ngene_buffer, vb); | ||
1143 | struct ngene_vopen *vopen = q->priv_data; | ||
1144 | return ngene_prepare_buffer(q, vopen->ch, buf, vopen->fmt, | ||
1145 | vopen->width, vopen->height, field); | ||
1146 | } | ||
1147 | |||
1148 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
1149 | { | ||
1150 | struct ngene_buffer *buf = container_of(vb, struct ngene_buffer, vb); | ||
1151 | struct ngene_vopen *vopen = q->priv_data; | ||
1152 | ngene_dma_free(q, vopen->ch, buf); | ||
1153 | } | ||
1154 | |||
1155 | static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
1156 | { | ||
1157 | struct ngene_buffer *buf = container_of(vb, struct ngene_buffer, vb); | ||
1158 | struct ngene_vopen *vopen = q->priv_data; | ||
1159 | struct ngene_channel *chan = vopen->ch; | ||
1160 | |||
1161 | buf->vb.state = STATE_QUEUED; | ||
1162 | list_add_tail(&buf->vb.queue, &chan->capture); | ||
1163 | } | ||
1164 | |||
1165 | static struct videobuf_queue_ops ngene_video_qops = { | ||
1166 | .buf_setup = buffer_setup, | ||
1167 | .buf_prepare = buffer_prepare, | ||
1168 | .buf_queue = buffer_queue, | ||
1169 | .buf_release = buffer_release, | ||
1170 | }; | ||
1171 | |||
1172 | int video_open(struct inode *inode, struct file *flip) | ||
1173 | { | ||
1174 | struct ngene_vopen *vopen = NULL; | ||
1175 | enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1176 | struct video_device *vd = video_devdata(flip); | ||
1177 | struct ngene_channel *chan = my_video_get_drvdata(vd); | ||
1178 | |||
1179 | vopen = kmalloc(sizeof(*vopen), GFP_KERNEL); | ||
1180 | if (!vopen) | ||
1181 | return -ENOMEM; | ||
1182 | memset(vopen, 0, sizeof(*vopen)); | ||
1183 | flip->private_data = vopen; | ||
1184 | v4l2_prio_open(&chan->prio, &vopen->prio); | ||
1185 | vopen->ch = chan; | ||
1186 | vopen->picxcount = 0; | ||
1187 | vopen->type = type; | ||
1188 | videobuf_queue_init(&vopen->vbuf_q, &ngene_video_qops, | ||
1189 | chan->dev->pci_dev, &chan->s_lock, | ||
1190 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1191 | V4L2_FIELD_INTERLACED, | ||
1192 | sizeof(struct ngene_buffer), vopen); | ||
1193 | |||
1194 | vopen->ovfmt = ngene_formats; | ||
1195 | chan->videousers++; | ||
1196 | if (chan->dev->card_info->switch_ctrl) | ||
1197 | chan->dev->card_info->switch_ctrl(chan, 2, 1); | ||
1198 | return 0; | ||
1199 | } | ||
1200 | |||
1201 | int video_close(struct inode *inode, struct file *filp) | ||
1202 | { | ||
1203 | struct ngene_vopen *vopen = filp->private_data; | ||
1204 | struct ngene_channel *chan = vopen->ch; | ||
1205 | |||
1206 | chan->videousers--; | ||
1207 | if (!chan->videousers) { | ||
1208 | if (chan->dev->card_info->switch_ctrl) | ||
1209 | chan->dev->card_info->switch_ctrl(chan, 2, 0); | ||
1210 | ngene_analog_stop_feed(chan); | ||
1211 | } | ||
1212 | videobuf_mmap_free(&vopen->vbuf_q); | ||
1213 | v4l2_prio_close(&chan->prio, &vopen->prio); | ||
1214 | filp->private_data = NULL; | ||
1215 | kfree(vopen); | ||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | /****************************************************************************/ | ||
1220 | |||
1221 | static int vid_do_ioctl(struct inode *inode, struct file *file, | ||
1222 | unsigned int cmd, void *parg) | ||
1223 | { | ||
1224 | struct ngene_vopen *vopen = file->private_data; | ||
1225 | struct ngene_channel *chan = vopen->ch; | ||
1226 | struct ngene *dev = chan->dev; | ||
1227 | struct i2c_adapter *adap = &chan->i2c_adapter; | ||
1228 | int retval = 0; | ||
1229 | int err = 0; | ||
1230 | |||
1231 | switch (cmd) { | ||
1232 | |||
1233 | case VIDIOC_S_CTRL: | ||
1234 | { | ||
1235 | struct v4l2_control *c = parg; | ||
1236 | |||
1237 | err = v4l2_prio_check(&chan->prio, &vopen->prio); | ||
1238 | if (err) | ||
1239 | return err; | ||
1240 | |||
1241 | if (c->id == V4L2_CID_AUDIO_MUTE) { | ||
1242 | if (c->value) | ||
1243 | (dev->channel[chan->number + 2]).audiomute = 1; | ||
1244 | else | ||
1245 | (dev->channel[chan->number + 2]).audiomute = 0; | ||
1246 | return 0; | ||
1247 | } | ||
1248 | if (c->value != V4L2_CID_AUDIO_MUTE) | ||
1249 | ngene_analog_stop_feed(chan); | ||
1250 | i2c_clients_command(adap, cmd, parg); | ||
1251 | return 0; | ||
1252 | } | ||
1253 | |||
1254 | case VIDIOC_S_TUNER: | ||
1255 | { | ||
1256 | err = v4l2_prio_check(&chan->prio, &vopen->prio); | ||
1257 | if (err != 0) | ||
1258 | return err; | ||
1259 | i2c_clients_command(adap, cmd, parg); | ||
1260 | return 0; | ||
1261 | } | ||
1262 | |||
1263 | case VIDIOC_S_FREQUENCY: | ||
1264 | { | ||
1265 | struct v4l2_frequency *f = parg; | ||
1266 | u8 drxa = dev->card_info->demoda[chan->number]; | ||
1267 | |||
1268 | if (chan->fe && chan->fe->ops.tuner_ops.set_frequency) | ||
1269 | chan->fe->ops.tuner_ops. | ||
1270 | set_frequency(chan->fe, f->frequency * 62500); | ||
1271 | if (drxa) | ||
1272 | ; | ||
1273 | } | ||
1274 | |||
1275 | case VIDIOC_S_INPUT: | ||
1276 | { | ||
1277 | err = v4l2_prio_check(&chan->prio, &vopen->prio); | ||
1278 | if (err != 0) | ||
1279 | return err; | ||
1280 | i2c_clients_command(adap, cmd, parg); | ||
1281 | return 0; | ||
1282 | } | ||
1283 | |||
1284 | case VIDIOC_G_STD: | ||
1285 | { | ||
1286 | v4l2_std_id *id = parg; | ||
1287 | *id = chan->tvnorms[chan->tvnorm].v4l2_id; | ||
1288 | return 0; | ||
1289 | } | ||
1290 | |||
1291 | case VIDIOC_S_STD: | ||
1292 | { | ||
1293 | v4l2_std_id *id = parg; | ||
1294 | unsigned int i; | ||
1295 | |||
1296 | err = v4l2_prio_check(&chan->prio, &vopen->prio); | ||
1297 | if (err != 0) | ||
1298 | return err; | ||
1299 | ngene_analog_stop_feed(chan); | ||
1300 | i2c_clients_command(adap, cmd, parg); | ||
1301 | for (i = 0; i < chan->tvnorm_num; i++) | ||
1302 | if (*id & chan->tvnorms[i].v4l2_id) | ||
1303 | break; | ||
1304 | if (i == chan->tvnorm_num) | ||
1305 | return -EINVAL; | ||
1306 | |||
1307 | chan->tvnorm = i; | ||
1308 | mdelay(50); | ||
1309 | ngene_analog_start_feed(chan); | ||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | case VIDIOC_G_FREQUENCY: | ||
1314 | case VIDIOC_G_INPUT: | ||
1315 | case VIDIOC_S_AUDIO: | ||
1316 | case VIDIOC_G_AUDIO: | ||
1317 | case VIDIOC_ENUMAUDIO: | ||
1318 | case VIDIOC_S_MODULATOR: | ||
1319 | case VIDIOC_G_MODULATOR: | ||
1320 | case VIDIOC_G_CTRL: | ||
1321 | { | ||
1322 | i2c_clients_command(adap, cmd, parg); | ||
1323 | return 0; | ||
1324 | } | ||
1325 | |||
1326 | case VIDIOC_G_TUNER: | ||
1327 | { | ||
1328 | struct v4l2_tuner *tuner = parg; | ||
1329 | if (tuner->index != 0) | ||
1330 | return -EINVAL; | ||
1331 | i2c_clients_command(adap, cmd, parg); | ||
1332 | |||
1333 | if (chan->fe && chan->fe->ops.tuner_ops.get_status) { | ||
1334 | u32 status; | ||
1335 | |||
1336 | chan->fe->ops.tuner_ops.get_status(chan->fe, &status); | ||
1337 | tuner->signal = status; | ||
1338 | } | ||
1339 | return 0; | ||
1340 | } | ||
1341 | |||
1342 | case VIDIOC_QUERYCTRL: | ||
1343 | { | ||
1344 | struct v4l2_queryctrl *c = parg; | ||
1345 | int i; | ||
1346 | |||
1347 | if ((c->id < V4L2_CID_BASE || | ||
1348 | c->id >= V4L2_CID_LASTP1) && | ||
1349 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
1350 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
1351 | return -EINVAL; | ||
1352 | for (i = 0; i < NGENE_CTLS; i++) | ||
1353 | if (ngene_ctls[i].id == c->id) | ||
1354 | break; | ||
1355 | if (i == NGENE_CTLS) { | ||
1356 | *c = no_ctl; | ||
1357 | return 0; | ||
1358 | } | ||
1359 | *c = ngene_ctls[i]; | ||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1363 | case VIDIOC_G_FMT: | ||
1364 | { | ||
1365 | struct v4l2_format *f = parg; | ||
1366 | ngene_g_fmt(vopen, f); | ||
1367 | } | ||
1368 | |||
1369 | case VIDIOC_S_FMT: | ||
1370 | { | ||
1371 | struct v4l2_format *f = parg; | ||
1372 | |||
1373 | ngene_analog_stop_feed(chan); | ||
1374 | return ngene_s_fmt(vopen, chan, f); | ||
1375 | } | ||
1376 | |||
1377 | case VIDIOC_ENUM_FMT: | ||
1378 | { | ||
1379 | struct v4l2_fmtdesc *f = parg; | ||
1380 | enum v4l2_buf_type type; | ||
1381 | unsigned int i; | ||
1382 | int index; | ||
1383 | |||
1384 | type = f->type; | ||
1385 | if (V4L2_BUF_TYPE_VBI_CAPTURE == type) { | ||
1386 | /* vbi | ||
1387 | index = f->index; | ||
1388 | if (0 != index) | ||
1389 | return -EINVAL; | ||
1390 | memset(f, 0, sizeof(*f)); | ||
1391 | f->index = index; | ||
1392 | f->type = type; | ||
1393 | f->pixelformat = V4L2_PIX_FMT_GREY; | ||
1394 | strcpy(f->description, "vbi data"); */ | ||
1395 | return EINVAL; | ||
1396 | } | ||
1397 | |||
1398 | /* video capture + overlay */ | ||
1399 | index = -1; | ||
1400 | for (i = 0; i < NGENE_FORMATS; i++) { | ||
1401 | if (ngene_formats[i].fourcc != -1) | ||
1402 | index++; | ||
1403 | if ((unsigned int)index == f->index) | ||
1404 | break; | ||
1405 | } | ||
1406 | if (NGENE_FORMATS == i) | ||
1407 | return -EINVAL; | ||
1408 | |||
1409 | switch (f->type) { | ||
1410 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
1411 | break; | ||
1412 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
1413 | /* dprintk(KERN_DEBUG | ||
1414 | "Video Overlay not supported yet.\n"); */ | ||
1415 | return -EINVAL; | ||
1416 | break; | ||
1417 | default: | ||
1418 | return -EINVAL; | ||
1419 | } | ||
1420 | memset(f, 0, sizeof(*f)); | ||
1421 | f->index = index; | ||
1422 | f->type = type; | ||
1423 | f->pixelformat = ngene_formats[i].fourcc; | ||
1424 | strlcpy(f->description, ngene_formats[i].name, | ||
1425 | sizeof(f->description)); | ||
1426 | return 0; | ||
1427 | |||
1428 | } | ||
1429 | |||
1430 | case VIDIOC_QUERYSTD: | ||
1431 | { | ||
1432 | v4l2_std_id *id = parg; | ||
1433 | *id = V4L2_STD_625_50 | V4L2_STD_525_60; | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | case VIDIOC_ENUMSTD: | ||
1438 | { | ||
1439 | struct v4l2_standard *e = parg; | ||
1440 | unsigned int index = e->index; | ||
1441 | |||
1442 | if (index >= chan->tvnorm_num) | ||
1443 | return -EINVAL; | ||
1444 | v4l2_video_std_construct(e, chan->tvnorms[e->index].v4l2_id, | ||
1445 | chan->tvnorms[e->index].name); | ||
1446 | e->index = index; | ||
1447 | return 0; | ||
1448 | } | ||
1449 | |||
1450 | case VIDIOC_QUERYCAP: | ||
1451 | { | ||
1452 | static char driver[] = {'n', 'G', 'e', 'n', 'e', '\0'}; | ||
1453 | static char card[] = {'M', 'k', '4', 'x', 'x', '\0'}; | ||
1454 | struct v4l2_capability *cap = parg; | ||
1455 | |||
1456 | memset(cap, 0, sizeof(*cap)); | ||
1457 | if (dev->nr == 0) | ||
1458 | card[3] = '0'; | ||
1459 | else | ||
1460 | card[3] = '1'; | ||
1461 | if (chan->number) | ||
1462 | card[4] = 'a'; | ||
1463 | else | ||
1464 | card[4] = 'b'; | ||
1465 | strlcpy(cap->driver, driver, sizeof(cap->driver)); | ||
1466 | strlcpy(cap->card, card, sizeof(cap->card)); | ||
1467 | cap->bus_info[0] = 0; | ||
1468 | cap->version = KERNEL_VERSION(0, 8, 1); | ||
1469 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE| | ||
1470 | V4L2_CAP_TUNER|V4L2_CAP_AUDIO| | ||
1471 | V4L2_CAP_READWRITE|V4L2_CAP_STREAMING; | ||
1472 | return 0; | ||
1473 | } | ||
1474 | |||
1475 | case VIDIOC_ENUMINPUT: | ||
1476 | { | ||
1477 | static char *inputname[2] = { | ||
1478 | "AnalogTuner", | ||
1479 | "S-Video" | ||
1480 | }; | ||
1481 | |||
1482 | struct v4l2_input *i = parg; | ||
1483 | unsigned int index; | ||
1484 | index = i->index; | ||
1485 | |||
1486 | if (index > 1) | ||
1487 | return -EINVAL; | ||
1488 | |||
1489 | memset(i, 0, sizeof(*i)); | ||
1490 | i->index = index; | ||
1491 | strlcpy(i->name, inputname[index], sizeof(i->name)); | ||
1492 | |||
1493 | i->type = index ? V4L2_INPUT_TYPE_CAMERA : | ||
1494 | V4L2_INPUT_TYPE_TUNER; | ||
1495 | i->audioset = 0; | ||
1496 | i->tuner = 0; | ||
1497 | i->std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M; | ||
1498 | i->status = 0;/* V4L2_IN_ST_NO_H_LOCK; */ | ||
1499 | return 0; | ||
1500 | } | ||
1501 | |||
1502 | case VIDIOC_G_PARM: | ||
1503 | return -EINVAL; | ||
1504 | |||
1505 | case VIDIOC_S_PARM: | ||
1506 | return -EINVAL; | ||
1507 | |||
1508 | case VIDIOC_G_PRIORITY: | ||
1509 | { | ||
1510 | enum v4l2_priority *prio = parg; | ||
1511 | *prio = v4l2_prio_max(&chan->prio); | ||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | case VIDIOC_S_PRIORITY: | ||
1516 | { | ||
1517 | enum v4l2_priority *prio = parg; | ||
1518 | return v4l2_prio_change(&chan->prio, &vopen->prio, *prio); | ||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | case VIDIOC_CROPCAP: | ||
1523 | return -EINVAL; | ||
1524 | |||
1525 | case VIDIOC_G_CROP: | ||
1526 | return -EINVAL; | ||
1527 | |||
1528 | case VIDIOC_S_CROP: | ||
1529 | return -EINVAL; | ||
1530 | |||
1531 | case VIDIOC_G_FBUF: | ||
1532 | { | ||
1533 | struct v4l2_framebuffer *fb = parg; | ||
1534 | |||
1535 | *fb = chan->fbuf; | ||
1536 | fb->capability = 0; | ||
1537 | if (vopen->ovfmt) | ||
1538 | fb->fmt.pixelformat = vopen->ovfmt->fourcc; | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | case VIDIOC_REQBUFS: | ||
1543 | return videobuf_reqbufs(ngene_queue(vopen), parg); | ||
1544 | |||
1545 | case VIDIOC_QUERYBUF: | ||
1546 | return videobuf_querybuf(ngene_queue(vopen), parg); | ||
1547 | |||
1548 | case VIDIOC_QBUF: | ||
1549 | return videobuf_qbuf(ngene_queue(vopen), parg); | ||
1550 | |||
1551 | case VIDIOC_DQBUF: | ||
1552 | return videobuf_dqbuf(ngene_queue(vopen), parg, | ||
1553 | file->f_flags & O_NONBLOCK); | ||
1554 | |||
1555 | case VIDIOC_S_FBUF: | ||
1556 | { | ||
1557 | /* ngene_analog_stop_feed(chan); */ | ||
1558 | struct v4l2_framebuffer *fb = parg; | ||
1559 | const struct ngene_format *fmt; | ||
1560 | |||
1561 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) | ||
1562 | return -EPERM; | ||
1563 | |||
1564 | /* check args */ | ||
1565 | fmt = ngene_formats; /*format_by_fourcc(fb->fmt.pixelformat);*/ | ||
1566 | if (NULL == fmt) | ||
1567 | return -EINVAL; | ||
1568 | |||
1569 | if (0 == (fmt->flags & 0x02 /*FORMAT_FLAGS_PACKED*/)) | ||
1570 | return -EINVAL; | ||
1571 | |||
1572 | mutex_lock(&vopen->vbuf_q.lock); | ||
1573 | retval = -EINVAL; | ||
1574 | |||
1575 | if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { | ||
1576 | int maxLinesPerField; | ||
1577 | |||
1578 | if (fb->fmt.width > | ||
1579 | chan->tvnorms[chan->tvnorm].swidth) | ||
1580 | goto vopen_unlock_and_return; | ||
1581 | maxLinesPerField = chan->tvnorms[chan->tvnorm].sheight; | ||
1582 | if (fb->fmt.height > maxLinesPerField) | ||
1583 | goto vopen_unlock_and_return; | ||
1584 | } | ||
1585 | |||
1586 | /* ok, accept it */ | ||
1587 | chan->fbuf.base = fb->base; | ||
1588 | chan->fbuf.fmt.width = fb->fmt.width; | ||
1589 | chan->fbuf.fmt.height = fb->fmt.height; | ||
1590 | if (0 != fb->fmt.bytesperline) | ||
1591 | chan->fbuf.fmt.bytesperline = fb->fmt.bytesperline; | ||
1592 | else | ||
1593 | chan->fbuf.fmt.bytesperline = | ||
1594 | chan->fbuf.fmt.width * fmt->depth / 8; | ||
1595 | |||
1596 | retval = 0; | ||
1597 | vopen->ovfmt = fmt; | ||
1598 | chan->init.ovfmt = fmt; | ||
1599 | |||
1600 | vopen_unlock_and_return: | ||
1601 | mutex_unlock(&vopen->vbuf_q.lock); | ||
1602 | return retval; | ||
1603 | |||
1604 | } | ||
1605 | |||
1606 | case VIDIOC_ENUMOUTPUT: | ||
1607 | return -EINVAL; | ||
1608 | |||
1609 | case VIDIOC_TRY_FMT: | ||
1610 | { | ||
1611 | struct v4l2_format *f = parg; | ||
1612 | return ngene_try_fmt(vopen, chan, f); | ||
1613 | |||
1614 | } | ||
1615 | |||
1616 | case VIDIOC_STREAMON: | ||
1617 | { | ||
1618 | int res = ngene_resource(vopen); | ||
1619 | if (!check_alloc_res(chan, vopen, res)) | ||
1620 | return -EBUSY; | ||
1621 | ngene_analog_start_feed(chan); | ||
1622 | return videobuf_streamon(ngene_queue(vopen)); | ||
1623 | } | ||
1624 | |||
1625 | case VIDIOC_STREAMOFF: | ||
1626 | { | ||
1627 | int res = ngene_resource(vopen); | ||
1628 | int retval = videobuf_streamoff(ngene_queue(vopen)); | ||
1629 | ngene_analog_stop_feed(chan); | ||
1630 | if (retval < 0) | ||
1631 | return retval; | ||
1632 | |||
1633 | free_res(chan, vopen, res); | ||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | case VIDIOC_OVERLAY: | ||
1638 | return -EINVAL; | ||
1639 | |||
1640 | case VIDIOCGFBUF: | ||
1641 | { | ||
1642 | struct video_buffer *vb = parg; | ||
1643 | |||
1644 | memset(vb, 0, sizeof(*vb)); | ||
1645 | return 0; | ||
1646 | } | ||
1647 | |||
1648 | default: | ||
1649 | err = -EINVAL; | ||
1650 | break; | ||
1651 | } | ||
1652 | return err; | ||
1653 | } | ||
1654 | |||
1655 | /* | ||
1656 | static int vid_ioctl(struct inode *inode, struct file *file, | ||
1657 | unsigned int cmd, unsigned long arg) | ||
1658 | { | ||
1659 | return video_usercopy(inode, file, cmd, arg, vid_do_ioctl); | ||
1660 | } | ||
1661 | */ | ||
1662 | static unsigned int video_fix_command(unsigned int cmd) | ||
1663 | { | ||
1664 | switch (cmd) { | ||
1665 | } | ||
1666 | return cmd; | ||
1667 | } | ||
1668 | |||
1669 | static int vid_ioctl(struct inode *inode, struct file *file, | ||
1670 | unsigned int cmd, unsigned long arg) | ||
1671 | { | ||
1672 | void *parg = (void *)arg, *pbuf = NULL; | ||
1673 | char buf[64]; | ||
1674 | int res = -EFAULT; | ||
1675 | cmd = video_fix_command(cmd); | ||
1676 | |||
1677 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | ||
1678 | parg = buf; | ||
1679 | if (_IOC_SIZE(cmd) > sizeof(buf)) { | ||
1680 | pbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | ||
1681 | if (!pbuf) | ||
1682 | return -ENOMEM; | ||
1683 | parg = pbuf; | ||
1684 | } | ||
1685 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | ||
1686 | goto error; | ||
1687 | } | ||
1688 | res = vid_do_ioctl(inode, file, cmd, parg); | ||
1689 | if (res < 0) | ||
1690 | goto error; | ||
1691 | if (_IOC_DIR(cmd) & _IOC_READ) | ||
1692 | if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | ||
1693 | res = -EFAULT; | ||
1694 | error: | ||
1695 | kfree(pbuf); | ||
1696 | return res; | ||
1697 | } | ||
1698 | |||
1699 | static int ngene_mmap(struct file *file, struct vm_area_struct *vma) | ||
1700 | { | ||
1701 | struct ngene_vopen *vopen = file->private_data; | ||
1702 | return videobuf_mmap_mapper(ngene_queue(vopen), vma); | ||
1703 | } | ||
1704 | |||
1705 | #define MAGIC_BUFFER 0x20040302 | ||
1706 | void *my_videobuf_alloc(unsigned int size) | ||
1707 | { | ||
1708 | struct videobuf_buffer *vb; | ||
1709 | |||
1710 | vb = kmalloc(size, GFP_KERNEL); | ||
1711 | if (NULL != vb) { | ||
1712 | memset(vb, 0, size); | ||
1713 | videobuf_dma_init(&vb->dma); | ||
1714 | init_waitqueue_head(&vb->done); | ||
1715 | vb->magic = MAGIC_BUFFER; | ||
1716 | } | ||
1717 | return vb; | ||
1718 | } | ||
1719 | |||
1720 | static ssize_t driver_read(struct file *file, char *user, | ||
1721 | size_t count, loff_t *offset) | ||
1722 | { | ||
1723 | char __user *data = user; | ||
1724 | struct ngene_channel *chan; | ||
1725 | int retval = 0; | ||
1726 | struct videobuf_queue *q; | ||
1727 | struct ngene_vopen *vopen = file->private_data; | ||
1728 | int nonblocking = file->f_flags & O_NONBLOCK; | ||
1729 | enum v4l2_field field; | ||
1730 | unsigned long flags; | ||
1731 | unsigned size, nbufs, bytes; | ||
1732 | |||
1733 | if (!vopen) | ||
1734 | return 0; | ||
1735 | |||
1736 | chan = vopen->ch; | ||
1737 | q = &vopen->vbuf_q; | ||
1738 | |||
1739 | mutex_lock(&q->lock); | ||
1740 | nbufs = 1; | ||
1741 | size = 0; | ||
1742 | q->ops->buf_setup(q, &nbufs, &size); | ||
1743 | |||
1744 | if (NULL == q->read_buf) { | ||
1745 | /* need to capture a new frame */ | ||
1746 | retval = -ENOMEM; | ||
1747 | q->read_buf = my_videobuf_alloc(q->msize); | ||
1748 | if (NULL == q->read_buf) | ||
1749 | goto done; | ||
1750 | |||
1751 | q->read_buf->memory = V4L2_MEMORY_USERPTR; | ||
1752 | field = V4L2_FIELD_INTERLACED; | ||
1753 | retval = q->ops->buf_prepare(q, q->read_buf, field); | ||
1754 | if (0 != retval) { | ||
1755 | kfree(q->read_buf); | ||
1756 | q->read_buf = NULL; | ||
1757 | goto done; | ||
1758 | } | ||
1759 | |||
1760 | spin_lock_irqsave(q->irqlock, flags); | ||
1761 | q->ops->buf_queue(q, q->read_buf); | ||
1762 | spin_unlock_irqrestore(q->irqlock, flags); | ||
1763 | q->read_off = 0; | ||
1764 | } | ||
1765 | |||
1766 | ngene_analog_start_feed(chan); | ||
1767 | /* wait until capture is done */ | ||
1768 | retval = videobuf_waiton(q->read_buf, nonblocking, 1); | ||
1769 | if (0 != retval) | ||
1770 | goto done; | ||
1771 | videobuf_dma_sync(q, &q->read_buf->dma); | ||
1772 | |||
1773 | if (STATE_ERROR == q->read_buf->state) { | ||
1774 | /* catch I/O errors */ | ||
1775 | q->ops->buf_release(q, q->read_buf); | ||
1776 | kfree(q->read_buf); | ||
1777 | q->read_buf = NULL; | ||
1778 | retval = -EIO; | ||
1779 | goto done; | ||
1780 | } | ||
1781 | |||
1782 | /* copy to userspace */ | ||
1783 | bytes = count; | ||
1784 | if (bytes > q->read_buf->size - q->read_off) | ||
1785 | bytes = q->read_buf->size - q->read_off; | ||
1786 | retval = -EFAULT; | ||
1787 | |||
1788 | if (copy_to_user(data, q->read_buf->dma.vmalloc + q->read_off, bytes)) | ||
1789 | goto done; | ||
1790 | |||
1791 | retval = bytes; | ||
1792 | |||
1793 | q->read_off += bytes; | ||
1794 | if (q->read_off == q->read_buf->size) { | ||
1795 | /* all data copied, cleanup */ | ||
1796 | q->ops->buf_release(q, q->read_buf); | ||
1797 | kfree(q->read_buf); | ||
1798 | q->read_buf = NULL; | ||
1799 | } | ||
1800 | |||
1801 | done: | ||
1802 | mutex_unlock(&q->lock); | ||
1803 | |||
1804 | ngene_analog_stop_feed(chan); | ||
1805 | |||
1806 | return retval; | ||
1807 | } | ||
1808 | |||
1809 | static unsigned int ngene_poll(struct file *file, poll_table *wait) | ||
1810 | { | ||
1811 | struct ngene_vopen *vopen = file->private_data; | ||
1812 | struct ngene_buffer *buf; | ||
1813 | enum v4l2_field field; | ||
1814 | |||
1815 | if (check_res(vopen, RESOURCE_VIDEO)) { | ||
1816 | /* streaming capture */ | ||
1817 | if (list_empty(&vopen->vbuf_q.stream)) | ||
1818 | return POLLERR; | ||
1819 | buf = list_entry(vopen->vbuf_q.stream.next, | ||
1820 | struct ngene_buffer, vb.stream); | ||
1821 | } else { | ||
1822 | /* read() capture */ | ||
1823 | mutex_lock(&vopen->vbuf_q.lock); | ||
1824 | if (NULL == vopen->vbuf_q.read_buf) { | ||
1825 | /* need to capture a new frame */ | ||
1826 | if (locked_res(vopen->ch, RESOURCE_VIDEO)) { | ||
1827 | mutex_unlock(&vopen->vbuf_q.lock); | ||
1828 | return POLLERR; | ||
1829 | } | ||
1830 | vopen->vbuf_q.read_buf = | ||
1831 | videobuf_alloc(vopen->vbuf_q.msize); | ||
1832 | if (NULL == vopen->vbuf_q.read_buf) { | ||
1833 | mutex_unlock(&vopen->vbuf_q.lock); | ||
1834 | return POLLERR; | ||
1835 | } | ||
1836 | vopen->vbuf_q.read_buf->memory = V4L2_MEMORY_USERPTR; | ||
1837 | field = videobuf_next_field(&vopen->vbuf_q); | ||
1838 | if (0 != | ||
1839 | vopen->vbuf_q.ops-> | ||
1840 | buf_prepare(&vopen->vbuf_q, | ||
1841 | vopen->vbuf_q.read_buf, field)) { | ||
1842 | mutex_unlock(&vopen->vbuf_q.lock); | ||
1843 | return POLLERR; | ||
1844 | } | ||
1845 | vopen->vbuf_q.ops->buf_queue(&vopen->vbuf_q, | ||
1846 | vopen->vbuf_q.read_buf); | ||
1847 | vopen->vbuf_q.read_off = 0; | ||
1848 | } | ||
1849 | mutex_unlock(&vopen->vbuf_q.lock); | ||
1850 | buf = (struct ngene_buffer *)vopen->vbuf_q.read_buf; | ||
1851 | } | ||
1852 | |||
1853 | poll_wait(file, &buf->vb.done, wait); | ||
1854 | if (buf->vb.state == STATE_DONE || buf->vb.state == STATE_ERROR) | ||
1855 | return POLLIN | POLLRDNORM; | ||
1856 | return 0; | ||
1857 | } | ||
1858 | |||
1859 | static const struct file_operations ngene_fops = { | ||
1860 | .owner = THIS_MODULE, | ||
1861 | .read = driver_read, | ||
1862 | .write = 0, | ||
1863 | .open = video_open, | ||
1864 | .release = video_close, | ||
1865 | .ioctl = vid_ioctl, | ||
1866 | .poll = ngene_poll, | ||
1867 | .mmap = ngene_mmap, | ||
1868 | }; | ||
1869 | |||
1870 | static struct video_device ngene_cinfo = { | ||
1871 | .name = "analog_Ngene", | ||
1872 | .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_SCALES, | ||
1873 | .fops = &ngene_fops, | ||
1874 | .minor = -1, | ||
1875 | }; | ||
1876 | |||
1877 | void ngene_v4l2_remove(struct ngene_channel *chan) | ||
1878 | { | ||
1879 | video_unregister_device(chan->v4l_dev); | ||
1880 | } | ||
1881 | |||
1882 | int ngene_v4l2_init(struct ngene_channel *chan) | ||
1883 | { | ||
1884 | int ret = 0; | ||
1885 | struct video_device *v_dev; | ||
1886 | |||
1887 | chan->evenbuffer = NULL; | ||
1888 | chan->dma_on = 0; | ||
1889 | |||
1890 | v_dev = video_device_alloc(); | ||
1891 | *v_dev = ngene_cinfo; | ||
1892 | /* v_dev->dev = &(chan->dev->pci_dev->dev); */ | ||
1893 | v_dev->release = video_device_release; | ||
1894 | v_dev->minor = -1; | ||
1895 | video_register_device(v_dev, VFL_TYPE_GRABBER, -1); | ||
1896 | snprintf(v_dev->name, sizeof(v_dev->name), "AnalognGene%d", | ||
1897 | v_dev->minor); | ||
1898 | chan->v4l_dev = v_dev; | ||
1899 | chan->minor = v_dev->minor; | ||
1900 | printk(KERN_INFO "nGene V4L2 device video%d registered.\n", | ||
1901 | v_dev->minor); | ||
1902 | |||
1903 | v_dev->dev = &chan->device; | ||
1904 | my_video_set_drvdata(chan->v4l_dev, chan); | ||
1905 | |||
1906 | v4l2_prio_init(&chan->prio); | ||
1907 | |||
1908 | if (chan->dev->card_info->io_type[chan->number] == NGENE_IO_HDTV) { | ||
1909 | chan->tvnorms = ngene_tvnorms_hd; | ||
1910 | chan->tvnorm_num = 1; | ||
1911 | } else { | ||
1912 | chan->tvnorms = ngene_tvnorms_sd; | ||
1913 | chan->tvnorm_num = NGENE_TVNORMS; | ||
1914 | } | ||
1915 | chan->tvnorm = 0; | ||
1916 | |||
1917 | spin_lock_init(&chan->s_lock); | ||
1918 | init_MUTEX(&chan->reslock); | ||
1919 | INIT_LIST_HEAD(&chan->capture); | ||
1920 | chan->users = 0; | ||
1921 | chan->videousers = 0; | ||
1922 | chan->init.ov.w.width = 384; | ||
1923 | chan->init.ov.w.height = 288; | ||
1924 | chan->init.fmt = ngene_formats; | ||
1925 | chan->init.width = 384; | ||
1926 | chan->init.height = 288; | ||
1927 | chan->tun_rdy = 0; | ||
1928 | chan->dec_rdy = 0; | ||
1929 | chan->tun_dec_rdy = 0; | ||
1930 | chan->lastbufferflag = -1; | ||
1931 | |||
1932 | if (chan->dev->card_info->avf[chan->number]) | ||
1933 | avf4910a_attach(&chan->i2c_adapter, | ||
1934 | chan->dev->card_info->avf[chan->number]); | ||
1935 | |||
1936 | return ret; | ||
1937 | } | ||
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 15505c2b2534..1c6f0e742ad7 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h | |||
@@ -857,17 +857,6 @@ struct ngene_buffer { | |||
857 | }; | 857 | }; |
858 | #endif | 858 | #endif |
859 | 859 | ||
860 | int ngene_command_stream_control(struct ngene *dev, | ||
861 | u8 stream, u8 control, u8 mode, u8 flags); | ||
862 | int ngene_command_nop(struct ngene *dev); | ||
863 | int ngene_command_i2c_read(struct ngene *dev, u8 adr, | ||
864 | u8 *out, u8 outlen, u8 *in, u8 inlen, int flag); | ||
865 | int ngene_command_i2c_write(struct ngene *dev, u8 adr, u8 *out, u8 outlen); | ||
866 | int ngene_command_imem_read(struct ngene *dev, u8 adr, u8 *data, int type); | ||
867 | int ngene_command_imem_write(struct ngene *dev, u8 adr, u8 data, int type); | ||
868 | int ngene_stream_control(struct ngene *dev, u8 stream, u8 control, u8 mode, | ||
869 | u16 lines, u16 bpl, u16 vblines, u16 vbibpl); | ||
870 | |||
871 | 860 | ||
872 | #endif | 861 | #endif |
873 | 862 | ||