static void cx18_process_eeprom(struct cx18 *cx) { struct tveeprom tv; cx18_read_eeprom(cx, &tv); switch (tv.model) { case 74000 ... 74999: cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; case 0x718: return; case 0xffffffff: CX18_INFO("Unknown EEPROM encoding\n"); return; case 0: CX18_ERR("Invalid EEPROM\n"); return; default: CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } cx->v4l2_cap = cx->card->v4l2_capabilities; cx->card_name = cx->card->name; cx->card_i2c = cx->card->i2c; CX18_INFO("Autodetected %s\n", cx->card_name); if (tv.tuner_type == TUNER_ABSENT) CX18_ERR("tveeprom cannot autodetect tuner!\n"); if (cx->options.tuner == -1) cx->options.tuner = tv.tuner_type; if (cx->options.radio == -1) cx->options.radio = (tv.has_radio != 0); if (cx->std != 0) return; if (tv.tuner_formats & V4L2_STD_PAL) { CX18_DEBUG_INFO("PAL tuner detected\n"); cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; } else if (tv.tuner_formats & V4L2_STD_NTSC) { CX18_DEBUG_INFO("NTSC tuner detected\n"); cx->std |= V4L2_STD_NTSC_M; } else if (tv.tuner_formats & V4L2_STD_SECAM) { CX18_DEBUG_INFO("SECAM tuner detected\n"); cx->std |= V4L2_STD_SECAM_L; } else { CX18_INFO("No tuner detected, default to NTSC-M\n"); cx->std |= V4L2_STD_NTSC_M; } }
static void cx18_process_eeprom(struct cx18 *cx) { struct tveeprom tv; cx18_read_eeprom(cx, &tv); /* Many thanks to Steven Toth from Hauppauge for providing the model numbers */ /* Note: the Samsung memory models cannot be reliably determined from the model number. Use the cardtype module option if you have one of these preproduction models. */ switch (tv.model) { case 74000 ... 74999: cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; case 0: CX18_ERR("Invalid EEPROM\n"); return; default: CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } cx->v4l2_cap = cx->card->v4l2_capabilities; cx->card_name = cx->card->name; cx->card_i2c = cx->card->i2c; CX18_INFO("Autodetected %s\n", cx->card_name); if (tv.tuner_type == TUNER_ABSENT) CX18_ERR("tveeprom cannot autodetect tuner!"); if (cx->options.tuner == -1) cx->options.tuner = tv.tuner_type; if (cx->options.radio == -1) cx->options.radio = (tv.has_radio != 0); if (cx->std != 0) /* user specified tuner standard */ return; /* autodetect tuner standard */ if (tv.tuner_formats & V4L2_STD_PAL) { CX18_DEBUG_INFO("PAL tuner detected\n"); cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; } else if (tv.tuner_formats & V4L2_STD_NTSC) { CX18_DEBUG_INFO("NTSC tuner detected\n"); cx->std |= V4L2_STD_NTSC_M; } else if (tv.tuner_formats & V4L2_STD_SECAM) { CX18_DEBUG_INFO("SECAM tuner detected\n"); cx->std |= V4L2_STD_SECAM_L; } else { CX18_INFO("No tuner detected, default to NTSC-M\n"); cx->std |= V4L2_STD_NTSC_M; } }
static void cx18_process_options(struct cx18 *cx) { int i, j; cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; cx->options.cardtype = cardtype[cx->num]; cx->options.tuner = tuner[cx->num]; cx->options.radio = radio[cx->num]; cx->std = cx18_parse_std(cx); if (cx->options.cardtype == -1) { CX18_INFO("Ignore card\n"); return; } cx->card = cx18_get_card(cx->options.cardtype - 1); if (cx->card) CX18_INFO("User specified %s card\n", cx->card->name); else if (cx->options.cardtype != 0) CX18_ERR("Unknown user specified type, trying to autodetect card\n"); if (cx->card == NULL) { if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_INFO("Autodetected Hauppauge card\n"); } } if (cx->card == NULL) { for (i = 0; (cx->card = cx18_get_card(i)); i++) { if (cx->card->pci_list == NULL) continue; for (j = 0; cx->card->pci_list[j].device; j++) { if (cx->dev->device != cx->card->pci_list[j].device) continue; if (cx->dev->subsystem_vendor != cx->card->pci_list[j].subsystem_vendor) continue; if (cx->dev->subsystem_device != cx->card->pci_list[j].subsystem_device) continue; CX18_INFO("Autodetected %s card\n", cx->card->name); goto done; } } } done: if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_ERR("Unknown card: vendor/device: %04x/%04x\n", cx->dev->vendor, cx->dev->device); CX18_ERR(" subsystem vendor/device: %04x/%04x\n", cx->dev->subsystem_vendor, cx->dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n"); } cx->v4l2_cap = cx->card->v4l2_capabilities; cx->card_name = cx->card->name; cx->card_i2c = cx->card->i2c; }
static void cx18_process_options(struct cx18 *cx) { int i, j; cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */ cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs; cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize; cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ /* Ensure stream_buffers & stream_buf_size are valid */ for (i = 0; i < CX18_MAX_STREAMS; i++) { if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */ cx->options.megabytes[i] <= 0 || /* User said 0 MB total */ cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */ cx->options.megabytes[i] = 0; cx->stream_buffers[i] = 0; cx->stream_buf_size[i] = 0; continue; } /* * YUV is a special case where the stream_buf_size needs to be * an integral multiple of 33.75 kB (storage for 32 screens * lines to maintain alignment in case of lost buffers). * * IDX is a special case where the stream_buf_size should be * an integral multiple of 1.5 kB (storage for 64 index entries * to maintain alignment in case of lost buffers). * */ if (i == CX18_ENC_STREAM_TYPE_YUV) { cx->stream_buf_size[i] *= 1024; cx->stream_buf_size[i] -= (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE); if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE) cx->stream_buf_size[i] = CX18_UNIT_ENC_YUV_BUFSIZE; } else if (i == CX18_ENC_STREAM_TYPE_IDX) { cx->stream_buf_size[i] *= 1024; cx->stream_buf_size[i] -= (cx->stream_buf_size[i] % CX18_UNIT_ENC_IDX_BUFSIZE); if (cx->stream_buf_size[i] < CX18_UNIT_ENC_IDX_BUFSIZE) cx->stream_buf_size[i] = CX18_UNIT_ENC_IDX_BUFSIZE; } /* * YUV and IDX are special cases where the stream_buf_size is * now in bytes. * VBI is a special case where the stream_buf_size is fixed * and already in bytes */ if (i == CX18_ENC_STREAM_TYPE_VBI || i == CX18_ENC_STREAM_TYPE_YUV || i == CX18_ENC_STREAM_TYPE_IDX) { if (cx->stream_buffers[i] < 0) { cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 * 1024 / cx->stream_buf_size[i]; } else { /* N.B. This might round down to 0 */ cx->options.megabytes[i] = cx->stream_buffers[i] * cx->stream_buf_size[i]/(1024 * 1024); } } else { /* All other streams have stream_buf_size in kB here */ if (cx->stream_buffers[i] < 0) { cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 / cx->stream_buf_size[i]; } else { /* N.B. This might round down to 0 */ cx->options.megabytes[i] = cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; } /* convert from kB to bytes */ cx->stream_buf_size[i] *= 1024; } CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, " "%d bytes\n", i, cx->options.megabytes[i], cx->stream_buffers[i], cx->stream_buf_size[i]); } cx->options.cardtype = cardtype[cx->instance]; cx->options.tuner = tuner[cx->instance]; cx->options.radio = radio[cx->instance]; cx->std = cx18_parse_std(cx); if (cx->options.cardtype == -1) { CX18_INFO("Ignore card\n"); return; } cx->card = cx18_get_card(cx->options.cardtype - 1); if (cx->card) CX18_INFO("User specified %s card\n", cx->card->name); else if (cx->options.cardtype != 0) CX18_ERR("Unknown user specified type, trying to autodetect card\n"); if (cx->card == NULL) { if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_INFO("Autodetected Hauppauge card\n"); } } if (cx->card == NULL) { for (i = 0; (cx->card = cx18_get_card(i)); i++) { if (cx->card->pci_list == NULL) continue; for (j = 0; cx->card->pci_list[j].device; j++) { if (cx->pci_dev->device != cx->card->pci_list[j].device) continue; if (cx->pci_dev->subsystem_vendor != cx->card->pci_list[j].subsystem_vendor) continue; if (cx->pci_dev->subsystem_device != cx->card->pci_list[j].subsystem_device) continue; CX18_INFO("Autodetected %s card\n", cx->card->name); goto done; } } } done: if (cx->card == NULL) { cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", cx->pci_dev->vendor, cx->pci_dev->device); CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", cx->pci_dev->subsystem_vendor, cx->pci_dev->subsystem_device); CX18_ERR("Defaulting to %s card\n", cx->card->name); CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n"); } cx->v4l2_cap = cx->card->v4l2_capabilities; cx->card_name = cx->card->name; cx->card_i2c = cx->card->i2c; }
static void cx18_process_eeprom(struct cx18 *cx) { struct tveeprom tv; cx18_read_eeprom(cx, &tv); /* Many thanks to Steven Toth from Hauppauge for providing the model numbers */ /* Note: the Samsung memory models cannot be reliably determined from the model number. Use the cardtype module option if you have one of these preproduction models. */ switch (tv.model) { case 74301: /* Retail models */ case 74321: case 74351: /* OEM models */ case 74361: /* Digital side is s5h1411/tda18271 */ cx->card = cx18_get_card(CX18_CARD_HVR_1600_S5H1411); break; case 74021: /* Retail models */ case 74031: case 74041: case 74141: case 74541: /* OEM models */ case 74551: case 74591: case 74651: case 74691: case 74751: case 74891: /* Digital side is s5h1409/mxl5005s */ cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; case 0x718: return; case 0xffffffff: CX18_INFO("Unknown EEPROM encoding\n"); return; case 0: CX18_ERR("Invalid EEPROM\n"); return; default: CX18_ERR("Unknown model %d, defaulting to original HVR-1600 " "(cardtype=1)\n", tv.model); cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); break; } cx->v4l2_cap = cx->card->v4l2_capabilities; cx->card_name = cx->card->name; cx->card_i2c = cx->card->i2c; CX18_INFO("Autodetected %s\n", cx->card_name); if (tv.tuner_type == TUNER_ABSENT) CX18_ERR("tveeprom cannot autodetect tuner!\n"); if (cx->options.tuner == -1) cx->options.tuner = tv.tuner_type; if (cx->options.radio == -1) cx->options.radio = (tv.has_radio != 0); if (cx->std != 0) /* user specified tuner standard */ return; /* autodetect tuner standard */ #define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \ V4L2_STD_MN | \ V4L2_STD_PAL_I | \ V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \ V4L2_STD_DK) if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL) == TVEEPROM_TUNER_FORMAT_ALL) { CX18_DEBUG_INFO("Worldwide tuner detected\n"); cx->std = V4L2_STD_ALL; } else if (tv.tuner_formats & V4L2_STD_PAL) { CX18_DEBUG_INFO("PAL tuner detected\n"); cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; } else if (tv.tuner_formats & V4L2_STD_NTSC) { CX18_DEBUG_INFO("NTSC tuner detected\n"); cx->std |= V4L2_STD_NTSC_M; } else if (tv.tuner_formats & V4L2_STD_SECAM) { CX18_DEBUG_INFO("SECAM tuner detected\n"); cx->std |= V4L2_STD_SECAM_L; } else { CX18_INFO("No tuner detected, default to NTSC-M\n"); cx->std |= V4L2_STD_NTSC_M; } }